預先載入回應式圖片

您可以預先載入回應式圖片,協助瀏覽器從 srcset 中找出正確的圖片,然後再算繪 img 標記,大幅加快圖片載入速度。

回覆式圖片總覽

Browser Support

  • Chrome: 73.
  • Edge: 79.
  • Firefox: 78.
  • Safari: 17.2.

Source

假設您在寬度為 300 像素的螢幕上瀏覽網頁,而該網頁要求寬度為 1500 像素的圖片。由於螢幕無法處理這麼高的解析度,該網頁浪費了許多行動數據。理想情況下,瀏覽器會擷取比螢幕尺寸稍大的圖片版本,例如 325 像素。這項功能可確保圖片以高解析度顯示,不會浪費資料,且載入速度更快。

回應式圖片可讓瀏覽器為不同裝置擷取不同的圖片資源。如果未使用圖片 CDN,請為每張圖片儲存多個尺寸,並在 srcset 屬性中指定。w 值會告知瀏覽器各個版本的寬度,因此瀏覽器可以為任何裝置選擇合適的版本:

<img src="small.jpg" srcset="small.jpg 500w, medium.jpg 1000w, large.jpg 1500w" alt="…">

預先載入總覽

Browser Support

  • Chrome: 50.
  • Edge: 79.
  • Firefox: 85.
  • Safari: 11.1.

Source

預先載入功能可讓您在 HTML 中發現重要資源之前,先告知瀏覽器要盡快載入這些資源。這項功能特別適合用於不容易發現的資源,例如樣式表中的字型、背景圖片,或是從指令碼載入的資源。

<link rel="preload" as="image" href="important.png" fetchpriority="high">

imagesrcsetimagesizes

<link> 元素會使用 imagesrcsetimagesizes 屬性預先載入回應式圖片。請搭配 <link rel="preload"> 使用,並在 <img> 元素中使用 srcsetsizes 語法。

舉例來說,如果您想預先載入以以下方式指定的動態圖片:

 <img src="wolf.jpg" srcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" sizes="50vw" alt="A rad wolf">

方法是在 HTML 的 <head> 中加入以下內容:

<link rel="preload" as="image" href="wolf.jpg" imagesrcset="wolf_400px.jpg 400w, wolf_800px.jpg 800w, wolf_1600px.jpg 1600w" imagesizes="50vw" fetchpriority="high">

這會使用與 srcsetsizes 相同的資源選取邏輯,發出要求。

用途

以下是預先載入回應式圖片的幾個用途。

預先載入動態插入的回應式圖片

假設您要以動態方式載入主頁橫幅圖片,做為投影片放映的一部分,而且您知道要先顯示哪張圖片。在這種情況下,您可能希望盡快顯示該圖片,而不是等待載入投影片放映指令碼。

您可以在動態載入圖片庫的網站上檢查這個問題:

  1. 在新分頁中開啟這個投影片放映示範
  2. 按下 Control+Shift+J 鍵 (或 Mac 上的 Command+Option+J 鍵) 開啟開發人員工具。
  3. 按一下 [網路] 分頁標籤。
  4. 在「Throttling」(節流) 下拉式清單中,選取「Fast 3G」(快速 3G)
  5. 取消勾選「停用快取」核取方塊。
  6. 請重新載入頁面。
Chrome 開發人員工具的「Network」(網路) 面板,顯示瀑布圖,其中只有在某些 JavaScript 之後,才開始下載 JPEG 資源。
如果沒有預先載入,圖片會在瀏覽器執行完指令碼後開始載入。對於第一張圖片,這種延遲是不必要的。

在此使用 preload 可讓圖片提前開始載入,以便在瀏覽器需要顯示圖片時,圖片已準備就緒。

Chrome 開發人員工具的「網路」面板,顯示瀑布圖,其中 JPEG 資源與部分 JavaScript 並行下載。
預先載入第一張圖片,讓圖片與指令碼同時開始載入。

如要查看預先載入的差異,請檢查相同的動態載入圖片庫,但預先載入第一張圖片,方法是按照第一個範例的步驟操作。

使用 image-set 預先載入背景圖片

如果不同螢幕密度有不同的背景圖片,您可以使用 image-set 語法在 CSS 中指定這些圖片。瀏覽器接著可以根據螢幕的 DPR 選擇要顯示的圖片。

background-image: image-set( "cat.png" 1x, "cat-2x.png" 2x);

CSS 背景圖片的問題在於,瀏覽器只會在下載並處理網頁 <head> 中的所有 CSS 後,才會發現這些圖片。

您可以在範例網站上檢查這個問題,該網站具有回應式背景圖片

Chrome 開發人員工具的「網路」面板,顯示瀑布圖,其中 JPEG 資源只會在某些 CSS 之後才開始下載。
在這個範例中,圖片下載作業要等到 CSS 完全下載後才會開始,導致圖片顯示不必要的延遲。

預先載入回應式圖片可加快圖片載入速度。

<link rel="preload" as="image" imagesrcset="cat.png 1x, cat-2x.png 2x" fetchpriority="high">

如果省略 href 屬性,即可確保不支援 <link> 元素中 imagesrcset 的瀏覽器,但支援 CSS 中的 image-set,會下載正確的來源。不過,在這種情況下,預先載入不會帶來任何好處。

您可以在自動調整背景預先載入示範中,檢查上一個範例在預先載入自動調整背景圖片時的行為。

Chrome 開發人員工具的「網路」面板,顯示瀑布圖,其中 JPEG 資源與部分 CSS 平行下載。
在此,圖片和 CSS 會同時開始下載,讓圖片載入速度更快。

預先載入回應式圖片的實際效果

理論上,預先載入回應式圖片可以加快載入速度,但實際效果如何?

為回答這個問題,我建立了兩個示範 PWA 商店副本:一個不會預先載入圖片另一個則會預先載入部分圖片。由於網站使用 JavaScript 延遲載入圖片,因此預先載入出現在初始可視區域中的圖片,可能會有助於提升網站效能。

這會產生以下結果:沒有預先載入,以及圖片預先載入

WebPageTest 影片格比較結果:預先載入的圖片顯示速度快了大約 1.5 秒。
預先載入圖片可大幅加快圖片載入速度,進而提升使用者體驗。

預先載入和 <picture>

Web Performance Working Group 正在討論為 srcsetsizes 新增預先載入等效項目,但不是 <picture> 元素,因為該元素會處理「藝術指導」用途。

預先載入 <picture> 仍有許多技術問題待解決,但目前有幾種解決方法:

<picture>
    <source srcset="small_cat.jpg" media="(max-width: 400px)">
    <source srcset="medium_cat.jpg" media="(max-width: 800px)">
    <img src="large_cat.jpg">
</picture>

<picture> 元素的圖片來源選取邏輯會依序檢查 <source> 元素的 media 屬性,找出第一個相符的屬性,並使用附加的資源。

由於回應式預先載入沒有「順序」或「第一個相符項目」的概念,因此您需要將中斷點轉換為類似下列的內容:

<link rel="preload" href="small_cat.jpg" as="image" media="(max-width: 400px)" fetchpriority="high">
<link rel="preload" href="medium_cat.jpg" as="image" media="(min-width: 400.1px) and (max-width: 800px)" fetchpriority="high">
<link rel="preload" href="large_cat.jpg" as="image" media="(min-width: 800.1px)" fetchpriority="high">

預先載入和 type

<picture> 元素也支援在第一個 type 上比對,讓您提供不同的圖片格式,以便瀏覽器選取支援的第一個圖片格式。

預先載入僅部分支援這個用途:瀏覽器應只下載支援類型的預先載入。因此,您可以在預先載入中加入這項資訊,防止瀏覽器預先載入不支援的 MIME 類型:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

不過,與 <picture> 不同的是,它不會在第一個支援的型別停止。因此,如果多個類型都包含多個預先載入,系統就會預先載入所有圖片:

錯誤做法 - 預先載入多種型別:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">
<link rel="preload" href="image.jpg" type="image/jpg" as="image" fetchpriority="high">

改為執行這項操作:預先載入最偏好的類型:

<link rel="preload" href="image.avif" type="image/avif" as="image" fetchpriority="high">

預先載入最新格式 (本例為 AVIF) 可做為漸進式強化功能,支援該類型的瀏覽器會受益,其他瀏覽器則不會。

如果圖片在 HTML 中很容易找到,建議您避免預先載入,改為讓預先載入掃描器<picture><source> 元素中挑選圖片。無論如何,這都是最佳做法,特別是使用「擷取優先順序」來協助優先處理適當圖片時,因為這樣一來,系統就能根據瀏覽器支援情況預先載入確切的圖片。此外,如果圖片或網頁有所變更,預先載入的資源也不會過時,可降低這類風險。

對最大內容繪製 (LCP) 的影響

由於圖片可能是最大內容繪製 (LCP) 候選項目,預先載入圖片有助於提升網站的 LCP。

無論預先載入的圖片是否為回應式,當初始標記酬載中無法探索到圖片資源時,預先載入效果最佳。此外,如果網站是在用戶端而非伺服器上完整算繪標記,改善 LCP 的效果會更顯著。