圖片成效

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

您可以使用 <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 機型,都有 2 的 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-500.png、在 DPR 為 2 的裝置上使用 image-1000.jpg,以及在 DPR 為 3 的裝置上使用 image-1500.jpg

雖然這一切看起來都很簡單,但在為特定網頁選擇最佳圖片時,螢幕的 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: 561px) 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 1000-sm.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: 561px)"
    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 文件的大小會隨著每個變化版本增加。您可能會發現,每張圖片都會傳送多個千位元組的 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 根據 Accept 標頭在 Apache 伺服器上重寫圖片要求。

這與 圖片內容傳遞網路 (CDN) 的行為類似。圖片 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 屬性載入的圖片內在寬度。
請再試一次。

下一項:影片成效

雖然圖片可能是網站上最常見的媒體類型,但在成效方面,您還需要考量其他因素。影片是另一種常見的網路媒體類型,並有其成效考量。在本課程的下一單元中,我們將探討一些影片最佳化技巧,以及如何有效載入影片。