圖片通常是網路上最重且最常見的資源。因此,最佳化圖片可大幅提升網站效能。在大多數情況下,最佳化圖片代表傳送較少位元組以縮短網路時間,但您也可以透過提供適合使用者裝置大小的圖片,來最佳化傳送給使用者的位元組數量。
您可以使用 <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
)。
檔案格式
瀏覽器支援多種圖片檔案格式。WebP 和 AVIF 等新型圖片格式,可能比 PNG 或 JPEG 提供更好的壓縮效果,讓圖片檔案大小縮小,下載時間也隨之縮短。透過以新格式提供圖片,您可以縮短資源的載入時間,進而降低最大內容繪製 (LCP)。
WebP 是廣泛支援的格式,可在所有新型瀏覽器上運作。WebP 的壓縮效果通常比 JPEG、PNG 或 GIF 更好,且同時提供有損和無損壓縮。即使使用有損壓縮,WebP 也支援 Alpha 通道透明度,這是 JPEG 編碼器不提供的功能。
AVIF 是較新的圖片格式,雖然不像 WebP 那樣廣泛支援,但在各瀏覽器中享有相當不錯的支援。AVIF 支援有損和無損壓縮,且測試顯示在某些情況下,相較於 JPEG,可節省超過 50% 的檔案大小。AVIF 也提供寬廣色域 (WCG) 和高動態範圍 (HDR) 功能。
壓縮
圖片有兩種壓縮方式:
有損壓縮會透過量化降低圖片準確度,並且可能會使用色度子樣本捨棄其他顏色資訊。有損壓縮最適合用於含有大量雜訊和顏色的高密度圖片,通常是相片或含有類似內容的圖像。這是因為在這種細節豐富的圖片中,由有損壓縮產生的雜訊不太容易被察覺。不過,如果圖片含有銳利邊緣 (例如線條圖、類似的鮮明細節或文字),有損壓縮可能就沒那麼有效。有損壓縮可套用於 JPEG、WebP 和 AVIF 圖片。
無損壓縮會壓縮圖片,且不會造成資料遺失,進而縮減檔案大小。無損壓縮會根據相鄰像素的差異來描述像素。無損壓縮適用於 GIF、PNG、WebP 和 AVIF 圖片格式。
您可以使用 Squoosh、ImageOptim 或圖片最佳化服務壓縮圖片。壓縮時,並沒有適用於所有情況的通用設定。建議您嘗試不同的壓縮等級,直到在圖片品質和檔案大小之間取得良好平衡為止。部分進階圖片最佳化服務可自動為您執行這項操作,但可能不利於所有使用者的財務狀況。
<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>
元素。alt
、width
和 height
屬性是在 <img>
上定義,無論選取哪個 <source>
都會使用。
<source>
元素也支援 media
、srcset
和 sizes
屬性。與前述 <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 像素的寬度顯示所選圖片候選項目。在較小的裝置上,這會占用整個可視區域寬度。結合 media
和 srcset
屬性,您可以更精細地控管要使用的圖片。
如以下表格所示,系統會評估多個檢視區寬度和裝置像素比例:
可視區域寬度 (像素) | 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.jpg
和 image-1500-sm.jpg
會在小型檢視區顯示。由於在該大小和密度下,壓縮成果不會明顯可見,因此您可以進一步壓縮圖片,同時不會影響電腦裝置上的圖片品質。
或者,您也可以調整 srcset
和 media
屬性,避免在小型可視區域中提供大型圖片:
<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
的預設值可讓瀏覽器決定最適合使用者的值。
圖片示範
學以致用
哪些圖片格式支援無損壓縮?
哪些圖片格式支援有損壓縮?
寬度描述元 (例如 1000w
) 會向瀏覽器說明 srcset
屬性中指定的圖片候選項目?
sizes
屬性會向瀏覽器告知套用至 <img>
元素的資訊?
<img>
元素 srcset
中指定的候選項目。<img>
元素的 srcset
屬性載入的圖片內在寬度。下一項:影片成效
雖然圖片可能是網站上最常見的媒體類型,但在成效方面,您還需要考量其他因素。影片是另一種常見的網路媒體類型,並有其成效考量。在本課程的下一單元中,我們將探討一些影片最佳化技巧,以及如何有效載入影片。