多媒體:影像

媒體(即圖片和影片)佔普通網站下載位元組的 70% 以上。就下載效能而言,消除媒體並減小檔案大小是唾手可得的成果。本文著眼於最佳化圖片和影片以提高 Web 效能。

預備知識 已安裝基本軟體,並具備 客戶端 Web 技術 的基礎知識。
目標 瞭解各種圖片格式、它們對效能的影響,以及如何減少圖片對整體頁面載入時間的影響。

注意: 這是關於最佳化 Web 多媒體傳輸的高階介紹,涵蓋了一般原則和技術。有關更深入的指南,請參閱 https://web.dev/learn/images

為什麼要最佳化多媒體?

對於普通網站,51% 的頻寬來自圖片,其次是影片佔 25%,因此可以肯定地說,處理和最佳化多媒體內容非常重要。

你需要考慮資料使用情況。許多人使用有流量上限的資料套餐,甚至按需付費,他們實際上是按兆位元組付費的。這也不是一個新興市場問題。根據 OFCOM 國家和地區技術追蹤器 - 2018 年上半年 (PDF) 的資料,截至 2018 年,英國仍有 24% 的人使用按需付費套餐。

你還需要考慮記憶體,因為許多移動裝置的 RAM 有限。重要的是要記住,圖片下載後需要儲存在記憶體中。

最佳化圖片傳輸

儘管圖片下載是最大的頻寬消費者,但它對感知效能的影響遠低於許多人的預期(主要是因為頁面文字內容會立即下載,使用者可以看到圖片隨著它們的到來而渲染)。然而,為了獲得良好的使用者體驗,訪問者儘快看到它們仍然很重要。

載入策略

大多數網站最大的改進之一是懶載入首屏以下區域的圖片,而不是在初始頁面載入時全部下載,無論訪問者是否會滾動檢視它們。瀏覽器透過 <img> 元素上的 loading="lazy" 屬性提供此功能,還有許多客戶端 JavaScript 庫可以做到這一點。

除了載入圖片子集之外,您還應該檢視圖片本身的格式

  • 您是否正在載入最優的檔案格式?
  • 您是否已很好地壓縮圖片?
  • 您是否正在載入正確的尺寸?

最優格式

最優檔案格式通常取決於圖片的特性。

注意: 有關圖片型別的一般資訊,請參閱圖片檔案型別和格式指南

SVG 格式更適用於顏色少且非照片級的圖片。這需要以向量圖形格式提供原始檔。如果此類圖片僅以點陣圖形式存在,則PNG 將是首選的備用格式。此類圖案的示例有標誌、插圖、圖表或圖示(注意:SVG 遠優於圖示字型!)。這兩種格式都支援透明度。

PNG 可以以三種不同的輸出組合儲存

  • 24 位顏色 + 8 位透明度 — 以犧牲大小為代價提供全色準確度和平滑透明度。您可能希望避免這種組合,轉而使用 WebP(參見下文)。
  • 8 位顏色 + 8 位透明度 — 提供不超過 255 種顏色,但保持平滑透明度。大小不會太大。這些是您可能想要的 PNG。
  • 8 位顏色 + 1 位透明度 — 提供不超過 255 種顏色,並且只提供每畫素無透明或完全透明,這使得透明邊界顯得生硬和鋸齒狀。大小很小,但代價是視覺保真度。

一個很好的 SVG 最佳化線上工具是 SVGOMG。對於 PNG,有 ImageOptim onlineSquoosh

對於不帶透明度的攝影圖案,有更廣泛的格式可供選擇。如果您想安全起見,那麼您會選擇經過良好壓縮的 Progressive JPEG。Progressive JPEG 與普通 JPEG 不同,它會漸進式渲染(因此得名),這意味著使用者會看到一個低解析度版本,隨著圖片下載,清晰度會逐漸提高,而不是圖片以全解析度從上到下載入,甚至只在完全下載後才渲染。一個好的壓縮器將是 MozJPEG,例如,可以在線上圖片最佳化工具 Squoosh 中使用。75% 的質量設定應該會產生不錯的效果。

其他格式在 JPEG 的壓縮能力方面有所改進,但並非所有瀏覽器都支援

  • WebP — 圖片和動圖的絕佳選擇。WebP 提供比 PNG 或 JPEG 更好的壓縮,並支援更高的色深、動畫幀、透明度等(但不支援漸進式顯示)。除 macOS Big Sur 或更早版本的 Safari 14 之外,所有主流瀏覽器都支援。

    注意: 儘管 Apple 宣佈 Safari 14 支援 WebP,但 Safari 16.0 之前的版本在 macOS 桌面版本 11/Big Sur 之前無法成功顯示 .webp 圖片。iOS 14 的 Safari 確實 成功顯示 .webp 圖片。

  • AVIF — 由於高效能和免版稅圖片格式(甚至比 WebP 更高效,但支援範圍不廣),是圖片和動畫圖片的不錯選擇。它現在受 Chrome、Edge、Opera 和 Firefox 支援。Squoosh 是將以前的圖片格式轉換為 AVIF 的良好線上工具。

  • JPEG2000 — 曾是 JPEG 的繼任者,但僅在 Safari 中受支援。也不支援漸進式顯示。

考慮到 JPEG-XR 和 JPEG2000 的狹窄支援,以及解碼成本的考量,JPEG 唯一的有力競爭者是 WebP。這就是為什麼你也可以以這種格式提供你的圖片。這可以透過帶有 type 屬性<source> 元素輔助的 <picture> 元素來完成。

如果所有這些聽起來有點複雜或對您的團隊來說工作量太大,那麼還有一些線上服務可以作為圖片 CDN 使用,它們會根據請求圖片的裝置或瀏覽器的型別自動提供正確的圖片格式。流行的選擇包括 CloudinaryImage EngineImageKitimgix

最後,如果您想在頁面中包含動畫圖片,請注意 Safari 允許在 <img><picture> 元素中使用影片檔案。這些還允許您為所有其他現代瀏覽器新增 Animated WebP

html
<picture>
  <source type="video/mp4" src="giphy.mp4" />
  <source type="image/webp" src="giphy.webp" />
  <img src="giphy.gif" alt="A GIF animation" />
</picture>

提供最優尺寸

在圖片傳輸中,“一刀切”的方法不會產生最佳結果,這意味著對於小螢幕,您會希望提供解析度較小的圖片,反之對於大螢幕也是如此。除此之外,您還會希望為那些擁有高 DPI 螢幕(例如“Retina”)的裝置提供更高解析度的圖片。因此,除了建立大量中間圖片變體之外,您還需要一種方法來向正確的瀏覽器提供正確的檔案。這就是您需要使用 media 和/或 sizes 屬性來升級您的 <picture><source> 元素的地方。響應式圖片做得好:<picture>srcset 指南 詳細解釋瞭如何組合所有這些屬性。

關於高 dpi 螢幕,需要記住兩個有趣的效應是

控制圖片下載的優先順序(和順序)

將最重要的圖片比不那麼重要的圖片更快地呈現給訪問者可以提高感知效能。

首先要檢查的是您的內容圖片是否使用 <img><picture> 元素,並且您的背景圖片是否在 CSS 中使用 background-image 定義——<img> 元素中引用的圖片比背景圖片具有更高的載入優先順序。

其次,隨著優先順序提示的採用,您可以透過在圖片標籤中新增 fetchPriority 屬性來進一步控制優先順序。圖片上優先順序提示的一個示例用例是輪播圖,其中第一張圖片的優先順序高於後續圖片。

渲染策略:防止圖片載入時出現卡頓

由於圖片是非同步載入的,並在首次繪製後繼續載入,如果它們的尺寸在載入前未定義,它們可能會導致頁面內容重排。例如,當圖片載入時文字被向下推。因此,設定 widthheight 屬性很重要,這樣瀏覽器就可以在佈局中為它們保留空間。

當 HTML <img> 元素中包含圖片的 widthheight 屬性時,瀏覽器可以在圖片載入之前計算圖片的寬高比。此寬高比用於保留顯示圖片所需的空間,減少甚至防止圖片下載並繪製到螢幕時發生佈局偏移。減少佈局偏移是良好使用者體驗和 Web 效能的重要組成部分。

瀏覽器在解析 HTML 時開始渲染內容,通常在所有資源(包括圖片)下載完成之前。包含尺寸使瀏覽器能夠為每張圖片預留一個大小正確的佔位符框,以便在首次渲染頁面時載入圖片時顯示。

Two screenshots the first without an image but with space reserved, the second showing the image loaded into the reserved space.

如果沒有 widthheight 屬性,則不會建立佔位符空間,從而在圖片載入後渲染頁面時在頁面中產生明顯的卡頓或佈局偏移。頁面重排和重繪是效能和可用性問題。

CLS 指標衡量頁面載入時的卡頓程度,即視口中可見內容移動了多少以及移動了多少。導致 CLS 差的主要罪魁禍首是未宣告尺寸的可替換元素,當資源載入時它們會重排,包括沒有尺寸或aspect-ratio的圖片、廣告、嵌入和 iframe,以及網頁字型。

在響應式設計中,當容器比圖片窄時,通常使用以下 CSS 來防止圖片溢位其容器

css
img {
  max-width: 100%;
  height: auto;
}

雖然這對於響應式佈局很有用,但當沒有包含寬度和高度資訊時,會導致卡頓和糟糕的 CLS,因為如果在解析 <img> 元素但圖片尚未載入之前沒有高度資訊,此 CSS 實際上會將高度設定為 0。當圖片在頁面最初渲染到屏幕後載入時,頁面會重排並重新繪製,從而建立佈局偏移,因為它為新確定的高度建立了空間。

瀏覽器有一種在實際影像載入之前確定影像大小的機制。當 <img><video><input type="button"> 元素設定了 widthheight 屬性時,其寬高比會在載入之前計算出來,並可供瀏覽器使用,使用提供的尺寸。

然後使用寬高比來計算高度,因此,正確的尺寸將應用於 <img> 元素,這意味著上述卡頓不會發生,或者如果列出的尺寸在影像載入時不是完全準確,則卡頓會最小化。

寬高比僅用於在影像載入時預留空間。一旦影像載入完成,載入影像的固有寬高比或 `aspect-ratio` 屬性的值將取代屬性中的寬高比。這確保了即使屬性尺寸不準確,它也能以正確的寬高比顯示。

儘管過去十年的開發者最佳實踐可能建議省略 HTML <img> 元素的 widthheight 屬性,但由於寬高比對映,包含這兩個屬性被認為是開發者最佳實踐。

對於任何背景圖片,務必設定一個 background-color 值,以便在圖片下載之前,任何疊加的內容仍然可讀。

總結

在本節中,我們探討了圖片最佳化。您現在對如何最佳化平均網站總頻寬的一半有了一個大致的瞭解。這只是消耗使用者頻寬並減慢頁面載入速度的媒體型別之一。接下來讓我們看看影片最佳化,它解決了接下來的 20% 頻寬消耗。