圖片資源,在我們的業務中可謂是佔據了非常大頭的一環,尤其是其對頻寬的消耗是十分巨大的。
對圖片的效能最佳化及體驗最佳化在今天就顯得尤為重要。本文,就將從各個方面闡述,在各種新特性滿頭飛的今天,我們可以如何儘可能的對我們的圖片資源,進行效能最佳化及體驗最佳化。
圖片型別的選取及 Picture 標籤的使用
首先,從圖片的型別上而言,除了常見的 PNG-8/PNG-24,JPEG,GIF 之外,我們更多的關注另外幾個較新的圖片格式:
- WebP
- JPEG XL
- AVIF
首先,透過一張表格,快速過一下這幾個圖片,我們將從圖片型別、透明通道、動畫、編解碼效能、壓縮演算法、顏色支援、記憶體佔用、相容性方面,對比它們:
圖片型別 | Alpha 通道 | 動畫 | 編解碼效能 | 壓縮演算法 | 顏色支援 | 記憶體佔用 | 相容性 | |
---|---|---|---|---|---|---|---|---|
GIF | 支援 | 支援 | 較高 | 無失真壓縮 | 索引色(256) | 基本一致 | ALL | |
PNG-8/PNG-24 | 支援 | 不支援 | 較高 | 無失真壓縮 | 索引色(256)\直接色 | 基本一致 | ALL | |
JPEG | 不支援 | 不支援 | 較高 | 有失真壓縮 | 直接色 | 基本一致 | ALL | |
WebP | 支援 | 支援 | 編解碼效能差(低配裝置更為顯著) | 有失真壓縮\無失真壓縮 | 直接色 | 基本一致 | 高版本 Chrome\Opera\Android | |
JPEG XL | 支援 | 支援 | 漸進式解碼 | 有失真壓縮\無失真壓縮 | 直接色 | 基本一致 | 部分高版本 Chrome\Opera\Firefox\Edge | |
AVIF | 支援 | 支援 | 編解碼效能一般 | 有失真壓縮\無失真壓縮 | 直接色 | 基本一致 | 高版本 Chrome\Opera\Android\Edge |
首先,瞭解瞭解上述的一些引數含義:
- Alpha 通道:圖片是否支援透明的特性
當然,需要指出的是,Alpha 沒有透明度的意思,不代表透明度。opacity 和 transparency 才和透明度有關,前者是不透明度,後者是透明度。比如 css 中的「opacity: 0.5」就是設定元素有 50% 的不透明度。後來 Alvy Ray Smith 提出每個畫素再增加一個 Alpha 通道,取值為0到1,用來儲存這個畫素是否對圖片有「貢獻」,0代表透明、1代表不透明。也就是說,「Alpha 通道」儲存一個值,其外在表現是「透明度」,Alpha 和透明度沒啥關係
- 動畫:很好理解,圖片是否支援多幀率動態圖片,類似於 GIF
- 編解碼效能:影像的解碼與編碼。這個很關鍵,很多人對待圖片容易忽檢視片的編解碼效能,解碼影像主要從影像檔案中讀出影像資料,而編碼則是將影像資料寫入影像檔案。解碼與編碼的過程正好相反。而這兩者的效能耗時會影響我們頁面的的展示效能。
壓縮演算法:該圖片格式是否支援壓縮,支援的話,圖片的壓縮又會分為無失真壓縮與有失真壓縮
有失真壓縮演算法是一種資料壓縮方法,經過此方法壓縮、解壓的資料會與原始資料不同但是非常接近。原理是藉由將次要的資訊資料捨棄,犧牲一些質量來減少資料量、提高壓縮比
無失真壓縮指資料經過壓縮後,資訊不受損失,還能完全恢復到壓縮前的原樣。無失真壓縮通常用於嚴格要求“經過壓縮、解壓縮的資料必須與原始資料一致”的場合。
顏色支援:會分為索引色與直接色,在過去,為了節省儲存空間,並非所有圖片都能支援所有顏色值,因此存在索引色這種最佳化方式。
索引顏色是一種以有限的方式管理數字影像顏色的技術,以節省計算機記憶體和檔案儲存,同時加速顯示重新整理和檔案傳輸。即用一個數字來代表(索引)一種顏色,在儲存圖片的時候,儲存一個數字的組合,同時儲存數字到圖片顏色的對映。這種方式只能儲存有限種顏色。索引色常見有1位(即黑白),8位(即灰階/256色),16位(即高彩),24位(即真彩),30/36/48位(即全綵)。
直接色使用四個數字來代表一種顏色,這四個數字分別代表這個顏色中紅色、綠色、藍色以及透明度(即 RGBA)。現在流行的顯示裝置可以在這四個維度分別支援256種變化,所以直接色可以表示2的32次方種顏色。
- 記憶體佔用:圖片對記憶體資源的佔用
- 相容性:影響圖片格式能否大規模推廣的核心要素之一
WebP vs JPEG XL vs AVIF: JPEG 替代之戰
因為傳統的 PNG-8/PNG-24,JPEG,GIF 各自或多或少都存在一些問題,近些年來它們的替代方案之爭也愈演愈烈,核心領跑者可能是 WebP、JPEG XL、AVIF。
再簡單瞭解瞭解它們:
WebP
WebP 最初由 Google 在 2010 年 9 月釋出,其特性總結如下:
- 可以同時提供無損/有失真壓縮(像 JPEG 一樣)和支援透明度(像 PNG 一樣)的圖片檔案格式
- 支援動畫效果(像 GIF 一樣)
- WebP 主要優勢在於有損編碼,其無損編碼的效能和壓縮比表現一般
- WebP 的缺點在於其編解碼效能不是特別理想
- 在相容性方面,除了 IE,基本已經得到了全系列瀏覽器支援
對於複雜的影像(比如照片)來說,WebP 無損編碼表現並不好,但有損編碼表現卻非常棒。相近質量的圖片解碼速度 WebP 相距 JPEG 也已經相差不大了,而檔案壓縮比卻能提升不少。
下圖是我之前還在 TX 的時候做的一個測試對比:
載入同樣張數的 JPEG 與 WebP 的耗時對比:
對於 WebP 圖片格式,簡單做個總結:
- 目前 WebP 與 JPEG 相比較,據資料考證,編碼速度慢 10 倍,解碼速度慢 1.5 倍
- WebP 雖然會增加額外的解碼時間,但由於大幅減少了檔案體積,縮短了載入的時間,大頁面圖片量較多的場景下,頁面的渲染速度是有較大加快的
- 目前而言,是 WebP、JPEG XL、AVIF 三者中相容性最好的
截止至(2023-02-05)的相容性圖:
JPEG XL
JPEG XL 由聯合影像專家組(開發原始 JPEG 標準的同一組織)於 2021 年釋出,旨在成為傳統 JPEG 的長期替代品。作為一種免版稅的開源標準,JPEG XL 的建立者希望其格式的開放效能夠吸引網路開發人員採用該標準,該格式的副檔名為 .jxl
,JXL 核心位元流於 2021 年 1 月凍結,檔案格式於 2021 年 4 月定稿。:
JPEG XL 中的 X 指 2000 年以來的多個 JPEG 標準的名稱:JPEG XT、JPEG XR、JPEG XS,而 L 表示 'long-term',表示“長期”。建立這種格式是為替換舊的JPEG檔案格式,並使用足夠長的時間。
其主要特點有:
- 與傳統影像格式(例如JPEG、GIF和PNG)相比,有著更佳的效率與更豐富的功能
- 全面支援廣色域和 HDR,支援 Alpha 通道,支援多幀(也就是動畫支援)
- 有失真壓縮時:相同的視覺質量,比 JPEG 小約 60%。
- 無失真壓縮時:比 PNG 減小約 35%(對於 HDR,減小 50%)。
- 支援無損 JPEG 轉碼,減小約 20% 檔案大小。
- 漸進式解碼,專為支援不同顯示解析度的響應式載入
- 開源免費:具有使用三條款版BSD許可證的開源參考實現的免版稅格式
看看同一張圖片,相同質量下的大小表現:
資料來源:技術週刊 2021-04-15:2021最值得期待的新技術 JPEG XL
JPEG XL 是目前而言,最有可能全面替代傳統圖片格式(Gif、PNG、JPEG)的下一代標準,當然,在今天,需要看看其相容性:
好吧,目前的相容有點離譜。Chrome 從 91 版本開始已經實驗室性質支援了 .jxl
格式的圖片,需要透過 --enable-features=JXL
配置開啟,遺憾的是,從 Chrome 110 開始,Chrome 又不再支援 JPEG XL 。
有趣的是,Chrome 從 110 版本開始中棄用了對 JPEG-XL 的支援,谷歌的回答是,人們對 JPEG-XL 沒有足夠的興趣,並且與現有格式相比也沒有足夠的優勢。谷歌之前一直對 JPEG 的支援都是實驗性的性質的,他們認為 JPEG XL 缺乏生態系統支援,並且該格式沒有足夠多的好處(相對 WebP 和 AVIF)。也就是說,目前而言,Chrome 對 WebP 和 AVIF 等替代格式更感興趣。
AVIF
最後,我們再來看看 AVIF 格式圖片。
AVIF 是由開放媒體聯盟 (AOM) 開發並於 2019 年釋出的另一種最新影像格式。該格式基於 AV1 影片編解碼器,源自影片幀。其特點如下:
- 同樣的,與傳統影像格式(例如JPEG、GIF和PNG)相比,有著更佳的效率與更豐富的功能
- 支援 Alpha 通道,支援動態影像和動畫
- 支援有損、無失真壓縮。AVIF 檔案在低保真有損影像壓縮方面表現出色(比 JPEG XL 更優)。壓縮的 AVIF 影像保留了很高的圖片質量,避免了惱人的壓縮偽影等問題
- 相對而言,AVIF 的解碼和編碼速度不如 JPEG XL,它不支援漸進式渲染
- 最後,再看看相容性,目前(2023-02-05)它的相容性介於 WebP 與 JPEG XL 之間
看看 CaniUse 的資料:
下圖是 WebP vs JPEG XL vs AVIF 三者在圖片解碼上的效能表現:
圖片來源於:Encode.su -- JPEG XL vs. AVIF
從圖中可以看到,對於解碼效能的對比,結果居然是 WebP > AVIF > JPEG XL 。JPEG XL 的編解碼效能並沒有其描述的那麼強大。
圖片格式總結
總結一下,WebP、AVIF 和 JPEG XL 都是瀏覽器不廣泛支援的新型影像格式。雖然 WebP、AVIF 已經存在很長時間,但到今天,影響它們大規模使用的依舊是相容問題。它們各自有各自的特點與優勢,誰能勝出仍未知曉。
雖然 AVIF、JPEG XL 等新型圖片格式未得到任何瀏覽器的完全支援,但是在新版本的 Chrome、Firefox 和 Edge Chromium,可以使用配置標誌啟用對應影像格式,配合 HTML 的 Picture
標籤,我們還是可以一定程度上對我們的圖片進行格式選擇上的最佳化的。
這,就可以引出我們要說的第二部分 -- HTML Picture 標籤的使用。
Picture 元素的使用
HTML5 規範新增了 Picture Element。那麼 <picture>
元素的作用是什麼呢?
<picture>
元素透過包含零或多個 <source>
元素和一個 <img>
元素來為不同的顯示/裝置場景提供影像版本。瀏覽器會選擇最匹配的子 <source>
元素,如果沒有匹配的,就選擇 <img>
元素的 src 屬性中的 URL。然後,所選影像呈現在 <img>
元素佔據的空間中。
什麼意思呢?怎麼使用 <picture>
元素呢?
假設,沒有 <picture>
,只有 <img>
元素,我們想盡可能在支援一些現代圖片格式的瀏覽器上使用類似於上述我們提到的 WebP、AVIF 和 JPEG XL 等圖片格式,而不支援的瀏覽器回退使用常規的 JPEG、PNG 等。沒錯,就是一種漸進增強的思想,該怎麼辦呢?
只能是 JavaScript 去寫對應的邏輯,透過 JS 指令碼進行特性查詢,動態賦值給 <img>
的 src。
而有了 <picture>
後,瀏覽器將原生支援上述的一些列操作,我們來看看對應的語法:
<picture>
<!-- 可能是一些對相容性有要求的,但是效能表現更好的現代圖片格式-->
<source src="image.avif" type="image/avif">
<source src="image.jxl" type="image/jxl">
<source src="image.webp" type="image/webp">
<!-- 最終的兜底方案-->
<img src="image.jpg" type="image/jpeg">
</picture>
上述程式碼的含義是:
- 第 1 個
source
元素指向新 AVIF 格式的影像。如果瀏覽器支援 AVIF 影像,那麼它會選擇該影像檔案。否則,它將移動到下一個source
元素。 - 第 2個
source
元素指向新 JPEG XL 格式的影像。如果瀏覽器支援 JPEG XL 影像,那麼它會選擇該影像檔案。否則,它將移動到下一個source
元素。 - 第 3 個
source
元素指向一張WebP 格式的影像。如果瀏覽器能夠渲染 WebP 影像,它將使用該影像檔案。 - 否則瀏覽器將回退到使用
img
元素 src 屬性中的影像檔案。img 元素指向的是 JPEG 格式的圖片,它是最終的兜底方案。
這意味著現在我們可以在不犧牲向後相容性的情況下開始使用新的影像格式。
簡而言之,<picture>
元素的作用:
- 透過
<source>
給出一系列對相容性有所要求的現代圖片格式選項 - 透過
<img>
給出兜底的高相容性圖片格式選項 - 瀏覽器透過對給出的圖片格式做特性檢測,要決定載入哪個 URL,user agent 檢查每個
<source>
的 srcset、media 和 type 屬性,來選擇最匹配頁面當前佈局、顯示裝置特徵等的相容影像。 - 最終,所選影像呈現在
<img>
元素佔據的空間中
總結
總結一下,本文對常見的圖片格式以及最新的幾種未被大規模相容的圖片格式進行的對比,它們分別是:
- PNG-8/PNG-24
- JPEG
- GIF
- WebP
- JPEG XL
- AVIF
其後,著重介紹了 3 種現代圖片格式:WebP、JPEG XL、AVIF。相對於 JPEG 等傳統格式,它們在色彩表現、動畫支援、是否支援無損有失真壓縮、壓損比率、編解碼效能上有著更進一步的提升,正在成為下一階段 Web 影像的標準。
最後,介紹了 <picture>
元素,藉助它,我們能更好的實現圖片的漸進增強。
當然,本文只是現代圖片效能最佳化及體驗最佳化指南的第一篇,後續將給大家帶來圖片在:
- 如何適配不同的螢幕尺寸及 DPR
- 使用
aspect-ratio
實現圖片資源的比例固定及調整 <img>
圖片與背景圖片的取捨- 懶載入/非同步影像解碼方案
- 可訪問性以及圖片資源的容錯及錯誤處理
等相關知識的介紹,感興趣的可以提前關注。
最後
OK,本文到此結束,希望本文對你有所幫助 :)
更多精彩 CSS 技術文章彙總在我的 Github -- iCSS ,持續更新,歡迎點個 star 訂閱收藏。
如果還有什麼疑問或者建議,可以多多交流,原創文章,文筆有限,才疏學淺,文中若有不正之處,萬望告知。