圖片成效

圖片通常是網路上最重最常見的資源。因此,最佳化圖片可以大幅改善網站效能。在多數情況下,最佳化圖片是指傳送較少的位元組以縮短網路時間,但您也可以提供符合使用者裝置大小的圖片,藉此最佳化傳送至使用者的位元組量。

您可以使用 <img><picture> 元素,或是 CSS background-image 屬性在網頁中加入圖片。

圖片大小

使用圖片資源時,您可以先最佳化顯示大小正確的圖片。在本例中,「尺寸」一詞是指圖片的「尺寸」。在考慮沒有其他變數的情況下,以 500 像素 x 500 像素容器顯示的圖片最理想的尺寸為 500 x 500 像素。例如,使用正方形 1000 像素的圖片表示圖片視需要放大的兩倍。

然而,選擇適當的圖片大小需要許多變數,因此在各種情況下選擇適當圖片大小的工作也相當複雜。在 2010 年,iPhone 4 推出時,螢幕解析度 (640x960) 是 iPhone 3 (320x480) 的兩倍。不過,iPhone 4 螢幕的實際尺寸與 iPhone 3 大致相同。

以較高的解析度顯示所有文字會大幅縮小,原本大小只有一半。而 1 個像素會變為 2 個「裝置像素」。這就是所謂的裝置像素比例 (DPR)。iPhone 4 (以及許多 iPhone 型號) 推出後即推出 DPR。

再回頭查看先前的範例,如果裝置的 DPR 為 2,且圖片顯示為 500 x 500 像素的容器,那麼 1000 像素的正方形圖片 (稱為「內建尺寸」) 就是最佳尺寸。同樣地,如果裝置的 DPR 為 3,則正方形的 1500 像素圖片會是最佳大小。

srcset

<img> 元素支援 srcset 屬性,可讓您指定瀏覽器可能使用的圖片來源清單。每個指定的圖片來源都必須包含圖片網址和寬度「或」像素密度描述元。

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 1x, /image-1000.jpg 2x, /image-1500.jpg 3x"
>

上述 HTML 程式碼片段使用像素密度描述元提示瀏覽器,在 DPR 為 1 的裝置上,image-1000.jpg 用於 DPR 為 2 的裝置,image-1500.jpg 在 DPR 為 3 的裝置上會使用 image-1500.jpgimage-500.png

雖然這些建議看似一失真乾,但在為特定網頁選擇最佳圖片時,螢幕的 DPR 並不是唯一考量。另請考量網頁的版面配置

sizes

在所有可視區域,圖片尺寸必須採用相同的 CSS 像素大小時,先前的解決方案才能發揮作用。在許多情況下,頁面的版面配置和容器大小都會因為使用者的裝置而有所不同。

sizes 屬性可讓您指定一組來源大小,每種來源大小都包含一個媒體條件和值。sizes 屬性會說明 CSS 像素的正確顯示圖片大小。與 srcset 寬度描述元搭配使用時,瀏覽器可以選擇最適合使用者裝置的圖片來源。

<img
  alt="An image"
  width="500"
  height="500"
  src="/image-500.jpg"
  srcset="/image-500.jpg 500w, /image-1000.jpg 1000w, /image-1500.jpg 1500w"
  sizes="(min-width: 768px) 500px, 100vw"
>

在上述 HTML 程式碼片段中,srcset 屬性會指定瀏覽器可以選擇的圖片清單,並以半形逗號分隔。清單中的每個候選項目都包含一個圖片網址,後面接有表示圖片固有寬度的語法。圖片的內在尺寸是尺寸。舉例來說,1000w 的描述元表示圖片的內建寬度為 1000 像素。

瀏覽器會使用這項資訊評估 sizes 屬性中的媒體條件,在這個情況下,也會指示當裝置的可視區域寬度超過 768 像素時,圖片的寬度為 500 像素。在較小的裝置上,圖片會顯示為 100vw,或完整可視區域寬度。

瀏覽器隨後即可將這項資訊與 srcset 圖片來源清單合併,以找出最佳的圖片。舉例來說,如果使用者使用的是螢幕寬度為 320 像素且 DPR 為 3 的行動裝置,則圖片會顯示在 320 CSS pixels x 3 DPR = 960 device pixels 處。在本範例中,最接近的大小圖片為 image-1000.jpg,其內建寬度為 1000 像素 (1000w)。

檔案格式

瀏覽器支援多種不同的圖片檔案格式。WebPAVIF 等新型圖片格式的壓縮效果,可能比 PNG 或 JPEG 更好,進而縮小圖片檔大小,並縮短下載時間。您可以以現代化格式提供圖片,藉此縮短資源的載入時間,這可能會降低最大內容繪製 (LCP)

WebP 是廣受支援的格式,適用於所有新型瀏覽器。WebP 的壓縮通常優於 JPEG、PNG 或 GIF,提供無損壓縮無損壓縮。即使使用有損壓縮,WebP 也支援 Alpha 通道透明度,因為 JPEG 轉碼器未提供。

AVIF 是較新的圖片格式,雖然其不像 WebP 較廣泛支援,但對於各種瀏覽器沒有合理的支援,AVIF 支援有損和無損壓縮,而且在某些情況下,與 JPEG 相比,測試可節省超過 50%。AVIF 也提供廣色域 (WCG)高動態範圍 (HDR) 功能。

壓縮

對圖片有疑慮,系統會採用兩種壓縮類型:

  1. 壓縮失敗
  2. 壓縮失敗

有損壓縮的運作方式是透過量化降低圖片的準確度,您也可以使用色差向下取樣來捨棄其他顏色資訊。失真壓縮對於雜訊和色彩眾多的高密度圖片 (通常是內容相似的相片或圖像) 最有效。這是因為有損壓縮所產生的構件比較難以在這類詳細圖片中察覺。不過,若圖像包含銳利邊緣 (例如線條圖、看起來過於雜亂的細節或文字),失真壓縮可能效果較差。可以使用有損壓縮的 JPEG、WebP 和 AVIF 圖片。

無損壓縮會以在不遺失資料的情況下壓縮圖片,藉此縮減檔案大小。無損壓縮會根據與鄰近像素的差異來描述像素。無損壓縮適用於 GIF、PNG、WebP 和 AVIF 圖片格式。

您可以使用 SquooshImageOptim 或圖片最佳化服務來壓縮圖片。壓縮時,沒有適合所有情況的通用設定。建議您嘗試使用不同的壓縮等級,直到發現影像品質與檔案大小都有良好平衡。部分進階圖片最佳化服務可自動執行此作業,但可能無法為所有使用者帶來經濟效益。

<picture> 元素

<picture> 元素可讓您更靈活地指定多張圖片:

<picture>
  <source type="image/avif" srcset="image.avif">
  <source type="image/webp" srcset="image.webp">
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image.jpg"
  >
</picture>

<picture> 元素中使用 <source> 元素時,您可以新增 AVIF 和 WebP 圖片的支援功能,但如果瀏覽器不支援新格式,則會改用較相容的舊版圖片格式。使用此方法時,瀏覽器會挑選第一個相符的 <source> 元素。如果能夠以該格式算繪圖片,就會使用該圖片。否則,瀏覽器會移至下一個指定的 <source> 元素。在上述 HTML 程式碼片段中,AVIF 格式的優先順序高於 WebP 格式。如果不支援 AVIF 或 WebP,則會改用 JPEG 格式。

<picture> 元素需要在當中建立巢狀結構的 <img> 元素。altwidthheight 屬性是在 <img> 上定義,無論所選 <source> 為何,都會使用這項屬性。

<source> 元素也支援 mediasrcsetsizes 屬性。與前述的 <img> 範例類似,這些屬性會指出瀏覽器在不同可視區域中應選取的圖片。

<picture>
  <source
    media="(min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

media 屬性接受媒體條件。在上述範例中,系統會使用裝置的 DPR 做為媒體條件。DPR 大於或等於 1.5 的任何裝置都會使用第一個 <source> 元素。<source> 元素會通知瀏覽器,在可視區域寬度大於 768 像素的裝置上,所選圖片的候選寬度為 500 像素。在較小的裝置上,這會佔滿整個可視區域寬度。結合 mediasrcset 屬性,您可以更精細地控制要使用哪一張圖片。

如下表所示,系統會評估多種可視區域寬度和裝置像素比率:

可視區域寬度 (像素) 1 DPR 1.5 DPR 2 DPR 3 DPR
320 500.jpg 500.jpg 500.jpg 1000.jpg
480 500.jpg 500.jpg 1000.jpg 1500.jpg
560 500.jpg 1000.jpg 1000.jpg 1500.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

DPR 為 1 的裝置會下載 image-500.jpg 映像檔,其中包括大多數電腦使用者,都會以最小尺寸為 500 像素的像素檢視圖片。另一方面,DPR 為 3 的行動裝置使用者下載可能更大的 image-1500.jpg,也就是在 DPR 為 3 的電腦裝置上使用相同的圖片。

<picture>
  <source
    media="(min-width: 560px) and (min-resolution: 1.5x)"
    srcset="/image-1000.jpg 1000w, /image-1500.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <source
    media="(max-width: 560px) and (min-resolution: 1.5x)"
    srcset="/image-1000-sm.jpg 1000w, /image-1500-sm.jpg 1500w"
    sizes="(min-width: 768px) 500px, 100vw"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

在本範例中,系統會調整 <picture> 元素以加入額外的 <source> 元素,以便針對具有高 DPR 的寬螢幕使用不同的圖片:

可視區域寬度 (像素) 1 DPR 1.5 DPR 2 DPR 3 DPR
320 500.jpg 500.jpg 500.jpg 1000-sm.jpg
480 500.jpg 500.jpg 1000-sm.jpg 1500-sm.jpg
560 500.jpg 1000-sm.jpg 1000-sm.jpg 1500-sm.jpg
1024 500.jpg 1000.jpg 1000.jpg 1500.jpg
1920 500.jpg 1000.jpg 1000.jpg 1500.jpg

透過這項額外查詢,您可以看到 image-1000-sm.jpgimage-1500-sm.jpg 會顯示在較小的可視區域中。這項額外資訊可讓您進一步壓縮圖片,因為壓縮構件無法清楚顯示該大小和密度,同時不會影響電腦裝置的影像品質。

您也可以調整 srcsetmedia 屬性,避免在較小的可視區域中提供大型圖片:

<picture>
  <source
    media="(min-width: 560px)"
    srcset="/image-500.jpg, /image-1000.jpg 2x, /image-1500.jpg 3x"
  >
  <source
    media="(max-width: 560px)"
    srcset="/image-500.jpg 1x, /image-1000.jpg 2x"
  >
  <img
    alt="An image"
    width="500"
    height="500"
    src="/image-500.jpg"
  >
</picture>

在上述 HTML 程式碼片段中,我們移除了寬度描述元,改用裝置像素比例描述元。在行動裝置上提供的圖片上限為 /image-500.jpg/image-1000.jpg,即使在 DPR 為 3 的裝置上也一樣。

如何因應複雜情況

使用回應式圖片時,您可以找到每種圖片的各種大小變化和格式。在上述範例中,使用的是每種大小的變化版本,但排除 AVIF 和 WebP。您應該有多少變化版本?這和許多工程問題一樣,答案通常都是「視情況而定」。

雖然您可能會想推出多種變化版本來提供最佳品質,但每個額外的圖片變化版本都會付出代價,而且會降低使用瀏覽器快取的效率。只有一個變化版本時,每位使用者都會收到相同圖片,因此可以非常有效率進行快取。

另一方面,如果變化版本有許多種,每個變數都需要另一個快取項目。如果變數的快取項目已過期,且需要重新從原始伺服器擷取圖片,伺服器費用可能會增加,並可能會降低效能。

除此之外,HTML 文件的大小會隨著每個變化版本一同成長。您可以為每張圖片傳送數 KB 的 HTML。

根據 Accept 要求標頭提供圖片

Accept HTTP 要求標頭會告知伺服器使用者瀏覽器可理解的內容類型。您的伺服器可使用這項資訊提供最佳圖片格式,而不需在 HTML 回應中增加額外位元組。

if (request.headers.accept) {
  if (request.headers.accept.includes('image/avif')) {
    return reply.from('image.avif');
  } else if (request.headers.accept.includes('image/webp')) {
    return reply.from('image.webp');
  }
}

return reply.from('image.jpg');

上述的 HTML 程式碼片段是簡短的程式碼,可加到伺服器的 JavaScript 後端,以選擇並提供最佳圖片格式。如果要求 Accept 標頭包含 image/avif,系統就會提供 AVIF 圖片。否則,如果 Accept 標頭包含 image/webp,系統就會提供 WebP 圖片。如果以上兩種條件皆非,則系統會提供 JPEG 圖片。

您可以從幾乎所有類型的網路伺服器中,根據 Accept 要求標頭的內容修改回應,例如您可以使用 mod_rewrite 在 Apache 伺服器上重新編寫圖片要求Accept

這與您在圖片內容傳遞聯播網 (CDN) 中找到的行為不同。Image CDN 是最佳化圖片及根據使用者的裝置和瀏覽器傳送最佳格式的絕佳解決方案。

關鍵在於找出平衡、產生合理數量的候選圖片,並評估對使用者體驗的影響。不同的圖片可能會產生不同的結果,而每張圖片套用的最佳化措施取決於其頁面中的大小,以及使用者所用的裝置。例如,相較於電子商務產品資訊頁面上的縮圖,完整寬度的主頁橫幅可能需要更多的變化版本。

延遲載入

您可以使用 loading 屬性,指示瀏覽器在圖片顯示為可視區域時延遲載入圖片。lazy 屬性值會指示瀏覽器在圖片位於 (或接近) 可視區域附近時,不要下載圖片。這樣可以節省頻寬,讓瀏覽器可優先轉譯已可視區域中已有的重要內容。

decoding

decoding 屬性會指示瀏覽器應如何解碼圖片。async 值會指示瀏覽器以非同步方式解碼圖片,可能改善轉譯其他內容的時間。sync 值會告知瀏覽器應同時顯示圖片與其他內容。auto 預設值可讓瀏覽器判斷最適合使用者的選項。

圖片示範

學以致用

哪種圖片格式支援無損壓縮?

GIF。
答對了!
JPEG。
請再試一次。
.PNG 的格式上傳圖片。
答對了!
WebP:
答對了!
AVIF。
答對了!

哪種圖片格式支援失真壓縮?

GIF。
請再試一次。雖然 GIF 格式僅支援部分 256 種顏色的調色盤,但必須先完成有損編碼才能轉換成 GIF。
JPEG。
答對了!
.PNG 的格式上傳圖片。
請再試一次。
WebP:
答對了!
AVIF。
答對了!

寬度描述元 (例如 1000w) 會告知瀏覽器在 srcset 屬性中指定的圖片候選圖片為何?

圖片的「精簡」寬度,也就是在頁面套用樣式後,版面配置中圖片的尺寸。
請再試一次。
圖片的「內在」寬度,也就是圖片本身的尺寸。
答對了!

sizes 屬性會向瀏覽器說明套用該元素的 <img> 元素嗎?

表示 <img> 元素 srcset 中指定的候選文字,根據使用者目前可視區域的尺寸,載入。
答對了!
<img> 元素的 srcset 屬性載入的圖片內在寬度。
請再試一次。

下一項:影片成效

儘管圖片可能是網路上最常見的媒體類型,但就效能來說,圖片類型遠不及。影片是網路上另一種常見的媒體類型,且有本身效能考量。在本課程的下一個單元中,探索最佳化影片及有效率地載入影片的一些技巧。