多媒體:影像

媒體,主要是影像和影片,佔平均網站下載位元組數的 70% 以上。在下載效能方面,消除媒體和減小檔案大小是低垂的果實。本文介紹瞭如何最佳化影像和影片以提高 Web 效能。

先決條件 安裝基本軟體,以及對客戶端 Web 技術的基本瞭解。
目標 瞭解各種影像格式,它們對效能的影響,以及如何減少影像對頁面整體載入時間的影響。

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

為什麼要最佳化您的多媒體?

對於平均網站,其頻寬的 51% 來自影像,其次是影片,佔 25%,因此可以肯定地說,解決和最佳化多媒體內容很重要。

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

您還需要考慮記憶體,因為許多移動裝置的 RAM 有限。重要的是要記住,當影像下載時,它們需要儲存在記憶體中。

最佳化影像傳遞

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

載入策略

大多數網站的最大改進之一是延遲載入摺疊線以下的影像,而不是在初始頁面載入時全部下載它們,而不管訪問者是否滾動檢視它們。許多 JavaScript 庫可以為您實現此功能,例如lazysizes,瀏覽器供應商正在努力開發一個原生 lazyload 屬性,該屬性目前處於實驗階段。

除了載入影像子集之外,您還應該研究影像本身的格式

  • 您是否正在載入最優的檔案格式?
  • 您是否已很好地壓縮了影像?
  • 您是否正在載入正確的大小?

最優格式

最優檔案格式通常取決於影像的特徵。

注意: 有關影像型別的常規資訊,請參閱影像檔案型別和格式指南

SVG 格式更適合顏色較少且非照片寫實的影像。這需要原始碼以向量圖形格式可用。如果這樣的影像僅作為點陣圖存在,那麼PNG 將是首選的備用格式。這些型別圖案的示例包括徽標、插圖、圖表或圖示(注意:SVG 遠優於圖示字型!)。兩種格式都支援透明度。

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

  • 24 位顏色 + 8 位透明度 — 以大小為代價提供全色精度和平滑透明度。您可能希望避免這種組合,而選擇 WebP(見下文)。
  • 8 位顏色 + 8 位透明度 — 提供不超過 255 種顏色,但保持平滑的透明度。大小不是太大。這些可能是您想要的 PNG。
  • 8 位顏色 + 1 位透明度 — 提供不超過 255 種顏色,並且每個畫素僅提供無透明度或全透明度,這會使透明度邊界看起來很硬且參差不齊。大小很小,但代價是視覺保真度。

用於最佳化 SVG 的良好線上工具是SVGOMG。對於 PNG,有ImageOptim 線上Squoosh

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

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

  • WebP — 影像和動畫影像的絕佳選擇。WebP 提供比 PNG 或 JPEG 更好的壓縮,支援更高的顏色深度、動畫幀、透明度等(但不支援漸進顯示)。除 macOS 桌面的 Safari 14 及更早版本外,所有主要瀏覽器都支援。

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

  • AVIF — 由於高效能和免版稅的影像格式(甚至比 WebP 更有效,但支援範圍不如 WebP 廣泛),影像和動畫影像的絕佳選擇。現在 Chrome、Edge、Opera 和 Firefox 都支援它。Squoosh 是一個用於將以前的影像格式轉換為 AVIF 的良好線上工具。
  • JPEG2000 — 曾經是 JPEG 的繼任者,但僅在 Safari 中受支援。也不支援漸進顯示。

鑑於 JPEG-XR 和 JPEG2000 的支援範圍有限,並且還考慮瞭解碼成本,JPEG 的唯一真正競爭者是 WebP。這就是為什麼您也可以提供該格式的影像。這可以透過 <picture> 元素來完成,藉助 <source> 元素使用type 屬性

如果這一切聽起來有點複雜,或者感覺對您的團隊來說工作量太大,那麼您也可以使用一些線上服務作為影像 CDN,這些服務將根據請求影像的裝置或瀏覽器型別自動在執行時提供正確的影像格式。最大的兩個是CloudinaryImage Engine

最後,如果您想在頁面上包含動畫影像,那麼請知道 Safari 允許在 <img><picture> 元素中使用影片檔案。這些還允許您為所有其他現代瀏覽器新增動畫 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 螢幕(例如 "視網膜")的裝置提供更高解析度的影像。因此,除了建立大量中間影像變體外,您還需要一種方法來為正確的瀏覽器提供正確的檔案。這就是您需要使用media 和/或sizes 屬性來升級 <picture><source> 元素的地方。有關如何將所有這些屬性結合在一起的詳細文章,請參見此處

需要牢記的兩個與高 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 不佳的主要原因是未宣告尺寸的替換元素,這些元素在資產載入時會發生重排,包括影像、廣告、嵌入和 iframe,沒有大小或aspect-ratio 和 Web 字型。

在響應式設計中,當容器比影像窄時,通常使用以下 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 值,這樣在影像下載之前,任何疊加的內容仍然可以閱讀。

結論

在本節中,我們研究了影像最佳化。現在您對如何最佳化平均網站平均頻寬總量的 50% 有了基本的瞭解。這只是消耗使用者頻寬和減慢頁面載入速度的幾種媒體型別之一。讓我們來看看影片最佳化,解決下一個 20% 的頻寬消耗。