現代圖片性能優化及體驗優化指南 - 縮放精細化展示及避免佈局偏移、拉伸

来源:https://www.cnblogs.com/coco1s/archive/2023/02/23/17146704.html
-Advertisement-
Play Games

本文是系列第三篇。系列文章: 現代圖片性能優化及體驗優化指南 - 圖片類型及 Picture 標簽的使用 現代圖片性能優化及體驗優化指南 - 響應式圖片方案 圖片資源,在我們的業務中可謂是占據了非常大頭的一環,尤其是其對帶寬的消耗是十分巨大的。 對圖片的性能優化及體驗優化在今天就顯得尤為重要。本文, ...


本文是系列第三篇。系列文章:

  1. 現代圖片性能優化及體驗優化指南 - 圖片類型及 Picture 標簽的使用
  2. 現代圖片性能優化及體驗優化指南 - 響應式圖片方案

圖片資源,在我們的業務中可謂是占據了非常大頭的一環,尤其是其對帶寬的消耗是十分巨大的。

對圖片的性能優化及體驗優化在今天就顯得尤為重要。本文,就將從各個方面闡述,在各種新特性滿頭飛的今天,我們可以如何儘可能的對我們的圖片資源,進行性能優化及體驗優化。

圖片的寬高比、裁剪與縮放

OK,下麵進入到我們的第三個模塊,圖片的寬高比、裁剪與縮放。我們會介紹 4 個新的特性:

  • aspect-ratio
  • object-fit
  • object-position
  • image-rendering

使用 aspect-ratio 避免佈局偏移

很多時候,只能使用固定尺寸大小的圖片,我們的佈局可能是這樣:

對應的佈局:

<ul class="g-container">
    <li>
        <img src="http://placehold.it/150x100">
        <p>圖片描述</p>
    </li>
</ul>
ul li img {
    width: 150px;
}

當然,萬一假設後端介面出現一張非正常大小的圖片,上述不加保護的佈局就會出問題:

所以對於圖片,我們總是建議同時寫上高和寬,避免因為圖片尺寸錯誤帶來的佈局問題:

ul li img {
    width: 150px;
    height: 100px;
}

同時,給 <img> 標簽同時寫上高寬,可以在圖片未載入之前提前占住位置,避免圖片從未載入狀態到渲染完成狀態高寬變化引起的重排問題。

當然,到今天,我們還可以使用 aspect-ratio 設定圖片的高寬比。

aspect-ratio CSS 屬性為容器規定了一個期待的寬高比,這個寬高比可以用來計算自動尺寸以及為其他佈局函數服務。

像是上面的代碼,我們就可以替換成:

ul li img {
    width: 150px;
    aspect-ratio: 3 / 2;
}

當然,有的時候,我們的佈局是響應式動態在變化的,容器的寬度也是不確定的,因此,有了 aspect-ratio 之後,我們的寫法就可以更佳的舒服。

ul li img {
    width: 100%;
    aspect-ratio: 3 / 2;
}

這裡,容器基於 Flex 彈性佈局或者響應式佈局,其寬度是不固定的,但是圖片的寬高比是固定的,使用 aspect-ratio: 3 / 2 就能非常好的適配這種情況。

我們藉助了 aspect-ratio 這個 CSS 中較新的屬性來始終自動獲得正確的寬高比,無論其父元素的寬度如何變化。

當然,aspect-ratio 不僅僅只是能運用在這裡,在 aspect-ratio 出現之前,我們只能通過一些其它的 Hack 方式,譬如設置 padding-top 等方式模擬固定的寬高比。在 aspect-ratio 之後,我們終於有了設定容器固定寬高比的能力。

object-fit 避免圖片拉伸

當然,限制高寬也會出現問題,譬如圖片被拉伸了,非常的難看:

這個時候,我們可以藉助 object-fit,它能夠指定可替換元素的內容(也就是圖片)該如何適應它的父容器的高寬。

ul li img {
    width: 150px;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}

利用 object-fit: cover,使圖片內容在保持其寬高比的同時填充元素的整個內容框。

object-fit 的取值有 fillnonecontaincover,與 background-size 類似,可以類比記憶。

也可以看看這張圖,很易於理解:

object-fit 還有一個配套屬性 object-position,它可以控製圖片在其內容框中的位置。(類似於 background-position),預設是 object-position: 50% 50%,如果你不希望圖片居中展示,可以使用它去改變圖片實際展示的 position。

ul li img {
    width: 150px;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    object-position: 50% 100%;
}

像是這樣,object-position: 100% 50% 指明從底部開始展示圖片。這裡有一個很好的 Demo 可以幫助你理解 object-position

CodePen Demo -- Object position

使用 image-rendering 設置圖片縮放演算法

相對於上面幾個新特性,image-rendering 會更為冷門。

很多時候,我們設置一個圖片在頁面上的展示大小為 200px x 200px,但是圖片的原始尺寸可能是 800px x 800px,也可能是 50px x 50px

這個時候,我們就可以利用 image-rendering,設置圖片在縮放狀態下的展示演算法。

image-rendering 在特定的場景下,能夠起到奇效。

來看這樣一個有意思的 DEMO,假設我們有這樣一個原圖效果,它是一個二維碼,大小為 100px x 100px

如果我們將它放大,放到很大,明顯,這個二維碼會失真,像是這樣:

OK,在這種放大失真的情況想,可以使用 image-rendering 改變圖片縮放演算法,這裡我們試一下 image-rendering: pixelated

.img {
  image-rendering: pixelated;
}

效果變化,如下圖所示:

可以看到,image-rendering: pixelated 處理過的圖像,竟然變得如此清晰!

CodePen Demo -- QrCode Image-rendering demo

來看看 image-rendering 的幾個取值:

  • image-rendering: auto:自 Gecko 1.9(Firefox 3.0)起,Gecko 使用雙線性(bilinear)演算法進行重新採樣(高質量)。
  • image-rendering: smooth:使用能最大化圖像客觀觀感的演算法來縮放圖像
  • image-rendering: high-quality:與 smooth 相同,但更傾向於高質量的縮放。
  • image-rendering: crisp-edges:必須使用可有效保留對比度和圖像中的邊緣的演算法來對圖像進行縮放,並且,該演算法既不會平滑顏色,又不會在處理過程中為圖像引入模糊。合適的演算法包括最近鄰居(nearest-neighbor)演算法和其他非平滑縮放演算法,比如 2×SaI 和 hqx-* 系列演算法。此屬性值適用於像素藝術作品,例如一些網頁游戲中的圖像。
  • image-rendering: pixelated:放大圖像時,使用最近鄰居演算法,因此,圖像看著像是由大塊像素組成的。縮小圖像時,演算法與 auto 相同。

雖然規範定義了挺多值,但是實際上,現代瀏覽器基本暫時只支持:autopixelated、以及 -webkit-optimize-contrast(Chrome 下的 smooth)。

看描述都會挺懵逼的,實際使用的時候,最好每個都試一下驗證一下效果。總結而言,image-rendering 的作用是在圖像縮放時,提供不一樣的渲染方式,讓圖片的展示形態更為多樣化,或者說是儘可能的去減少圖片的失真帶來的信息損耗

我們再看一個 DEMO,原圖如下(例子來源於 W3C 規範文檔):

實際效果:

當然,看上去 pixelated 的效果挺好,這是由於這是一張偏向於矢量的圖片,細節不多,對於高精度的人物圖,就不太適用於 pixelated,容易把圖片馬賽克化。

真正規範希望的在放大後讓圖片儘可能不失真的 crisp-edges 效果,目前暫時沒有得到瀏覽器的實現。後面可以期待一下。

CodePen Demo -- Image-rendering demo

總結一下

這一章,我們介紹了 4 個較新的 CSS 特性:

  • aspect-ratio:控制容器的寬高比,避免產生佈局偏移及抖動
  • object-fit:設定內容應該如何適應到其使用高度和寬度確定的框,避免圖片拉伸
  • object-position:基於 object-fit,設置圖片實際展示的 position 範圍
  • image-rendering:控製圖片在縮放狀態下的展示演算法

合理利用它們,可以給用戶在圖片上以更好的體驗。

當然,本文是現代圖片性能優化及體驗優化指南的第三篇,後續將給大家帶來圖片在:

  • 懶載入/非同步圖像解碼方案
  • 可訪問性以及圖片資源的容錯及錯誤處理

上的現代解決方案,感興趣的可以提前關註。

最後

OK,本文到此結束,希望本文對你有所幫助

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 最近接到個需求,我們新產品上的外包側APP需要使用硬體唯一ID(不管怎麼升級怎麼操作,ID始終不變和硬體綁定),用來做許可權校驗。 由於瞭解到安卓ID或序列號都會在擦除升級後重新隨機生成,所以這裡使用硬體上的ID來作為唯一ID,接下來進入正題 此篇以安卓7.1系統為例 一,常用硬體信息ID 這 ...
  • 一、 獲取Push Token的方式 獲取Push Token有兩種方式:一種是調用getToken方法向Push服務端請求Token,當getToken方法返回為空時,Token可通過onNewToken方法返回,因此需要實現onNewToken方法;另一種是自動初始化,Token通過onNewT ...
  • 官方文檔https://nativesupport.dcloud.net.cn/AppDocs/usesdk/android.html一、將寫好的uniapp右鍵→發行→原生app-本地打包→生成本地打包App資源(它會要求你登錄賬號)二、它會生成一個文件夾三、點擊連接可以直接進入文件夾,路徑往上一 ...
  • 全局組件 微信小程式組件關係中,父組件使用子組件需要在父組件index.json中引入子組件,然後在父組件頁面中使用,這種組件的對應狀態是一對一的,一個組件對應一個頁面。如果有一個全局彈窗(登錄),那麼每個頁面引入一次組件會非常麻煩,這裡就需要封裝全局彈窗,在頁面直接引入使用即可。 微信小程式提供全 ...
  • Object(對象) for in 遍歷出對象可枚舉的"屬性",包含繼承的可枚舉屬性 var person = { name: '小明', birth: 1990, height: 1.70 }; for(var x in person){ console.log(x); console.log(p ...
  • 前言 JavaScript 原型是該語言中一個非常重要的概念。理解原型是理解 JavaScript 的關鍵。在本篇技術博客中,我們將深入探討 JavaScript 的原型概念,並介紹常用的操作對象原型的方法。(歡迎點評,歡迎指正!) 什麼是原型? 在 JavaScript 中,每個對象都有一個原型( ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 npm 是 node 捆綁的依賴管理器,常用程度可想而知。那麼你每天都在 npm/yarn run 的命令到底是如何運行項目的呢? 前端項目中運行 npm run xxx 的時候發生了什麼?大家都知道目前的 node 是捆綁 npm 的。 ...
  • 一、常規 在 JavaScript 中,apply、call、bind 是三個與函數調用相關的方法,它們都允許你在調用函數時手動設置函數的上下文(即 this 指向)。 1、apply 方法:apply 方法允許你調用一個函數,並且手動設置函數的上下文(即 this 指向)以及傳遞一個參數數組。其語 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...