
去年幫一個客戶接手網站的時候,我在媒體庫看到一張 4032×3024、7.8 MB 的手機直出照片,被塞在一個實際只有 760px 寬的內文欄位裡。那一頁的圖有九張,全部都是這樣來的。使用者要下載將近 60 MB 才看得完一篇文章,而他們的主機方案是共享主機、頻寬按月計費。這不是特例,是我看過的自架站裡最常見的狀態。
圖片優化這件事被講爛了,但多數教學的順序是反的。它們一開頭就叫你裝一個壓縮外掛,然後跟你說要轉 WebP。問題是,把一張 4032px 的圖壓縮成一張比較小的 4032px 圖,省下的是頻寬,省不掉「瀏覽器仍然要解碼一張四千像素寬的圖」這件事;而在你連 width、height 都沒寫的情況下,版面位移照樣發生,Core Web Vitals 的 CLS 照樣扣分。順序錯了,工具再貴也只補到一半。
這篇會把整套網站圖片優化拆成四個有先後關係的步驟:先把實際像素縮到需要的大小,再選格式與壓縮強度,接著補上尺寸宣告避免版面位移,最後才處理載入策略(哪張 lazy、哪張不能 lazy、srcset 怎麼配)。中間會把 WordPress 這一端的實作講完——媒體庫尺寸設定、big_image_size_threshold 這個很多人不知道存在的門檻、以及外掛、主機端、CDN 三條路線各自的適用情境。最後談 alt 文字,那一段的重點是「怎麼寫才同時對得起螢幕報讀器與 Google Images,而不是把關鍵字塞進去」。所有門檻值、格式支援度與屬性行為,一律引 web.dev、Google Search Central、MDN 與 Can I Use 的官方頁面,文末列出清單。
先講結論:正確的順序是四步,不是裝一個外掛
如果你只想看要做什麼、照著做,這一段就是全部。後面每一章都是在解釋為什麼。
- 第一步:把實際像素縮到用得到的大小。內文欄寬 760px 的網站,不需要保留 4032px 的原圖上線。這一步省下的量級最大,而且完全免費。
- 第二步:選格式並決定壓縮強度。照片走 WebP(必要時 AVIF),去背或含大面積純色的圖走 PNG 或無損 WebP,向量圖走 SVG。有損與無損的分界不是品味問題,是「這張圖裡有沒有文字與銳利邊緣」。
- 第三步:每一張
<img>都要有width與height。這是唯一一項被 Core Web Vitals 直接量測的圖片屬性——沒寫,CLS 就會被扣分,而 CLS 的良好門檻是 0.1。 - 第四步:決定誰 lazy、誰 eager。首屏那張(通常就是 LCP 元素)絕對不能 lazy,其餘的一律 lazy;同時把
srcset與sizes配對正確,讓手機不要下載桌機尺寸的檔案。
這四步有嚴格的先後關係。第一步沒做,第二步的壓縮率再高也是在壓縮一張本來就不該存在的大圖;第三步沒做,第四步的 lazy load 反而會讓版面位移更嚴重(後面會解釋為什麼)。我看過太多站是「第二步跟第四步做了、第一步跟第三步沒做」,結果 PageSpeed 分數一直卡在同一個位置,然後開始懷疑是不是主機不夠好。
這篇專講圖片。如果你要處理的是整體的 Core Web Vitals——包含 JavaScript 阻塞、快取設定、字型載入那些——Core Web Vitals 三項指標的整體修法那篇是更適合的起點,本篇算是它底下最深的一支。
為什麼圖片是多數 WordPress 站最大的效能瓶頸
先講一個反直覺的事實:「圖片是網頁最重的資源」這句話,在 2024 年之後只對了一半。
實際的數字現況
依 HTTP Archive 的《Web Almanac 2024》媒體與頁面重量章節,行動版首頁的圖片位元組中位數是 900 KB,JavaScript 是 558 KB、CSS 73 KB、字型 111 KB;桌機版首頁圖片是 1,054 KB、JavaScript 613 KB。到了內頁,情況翻轉:行動版內頁的圖片中位數降到 348 KB,而 JavaScript 是 582 KB。該章節自己的結論寫得很直白——圖片並不總是頁面重量的最大宗,內頁反而是 JavaScript 拿下這個「殊榮」。
那為什麼我還是說圖片是多數 WordPress 站最大的瓶頸?因為那個中位數是「已經被優化過的網路整體」,不是你的網站。中位數之所以壓在 900 KB,是因為大量使用 Shopify、Wix、Squarespace 這類代管平台的站點,平台在後端幫他們自動縮圖、轉檔、上 CDN。自架 WordPress 沒有那一層,除非你自己補。我看過的自架站,首頁圖片超過 3 MB 的比比皆是,那已經是中位數的三倍以上。
另外三個數字更能說明問題。同一份報告指出:行動版只有 32% 的圖片同時具備 height 與 width 屬性;有 9.5% 的 LCP 圖片元素竟然掛著原生 lazy loading(等於自己拖慢自己的最大內容繪製);圖片格式方面,WebP 在行動版佔 12%、AVIF 只有 1.0%。也就是說,即使到 2024 年底,網路上仍有將近九成的圖片沒有用上新世代格式,將近七成的圖片沒有寫尺寸。這幾件事都是幾乎零成本就能改掉的。
圖片同時打中三個 Core Web Vitals
依 web.dev 的官方定義,Core Web Vitals 的三項指標與良好門檻分別是:LCP(最大內容繪製)應在 2.5 秒內、INP(互動到下次繪製)應在 200 毫秒以內、CLS(累計版面位移)應維持在 0.1 以下。而評估基準是「頁面載入的第 75 百分位數,並區分行動與桌機」——不是平均值,這一點很重要,代表少數幾個很慢的載入也會把你拖下水。
圖片在三項裡佔了兩項的關鍵位置:
- LCP:多數內容型頁面的最大內容元素就是首圖。它什麼時候載完,幾乎等於 LCP 什麼時候發生。
- CLS:圖片載入後把下方內容推開,是最典型也最容易修的版面位移來源。web.dev 的 CLS 說明頁把「尺寸未知的圖片或影片」列為位移成因的第一項。
- INP:圖片的間接影響。大量高解析圖同時解碼會佔用主執行緒,讓使用者的點擊延後被回應。
decoding="async"就是為了這件事存在。
換句話說,三項指標裡有兩項可以靠純圖片作業拿下,第三項也會順帶改善。這是自架站裡投入產出比最高的一塊。
WordPress 特有的三個放大器
同樣是內容網站,WordPress 有三個結構性因素會把圖片問題放大。
第一,媒體庫預設收下原檔。你上傳什麼,它就存什麼(超過門檻的例外後面會講)。手機直出的照片動輒四千像素寬、EXIF 裡還帶著 GPS 座標,這些全都原封不動進了你的 uploads 資料夾。
第二,佈景主題與頁面建構器會重寫 <img> 標籤。WordPress 核心其實會幫你補 width、height、srcset、loading、decoding,但那是針對「核心產生的內容」。Elementor、Divi 這類建構器輸出的圖,屬性由建構器自己決定,核心那套邏輯不一定套得上。如果你的站是用建構器做的,Elementor 的基本運作方式值得先搞清楚,因為它的圖片模組與背景圖走的是完全不同的兩條路徑。同理,佈景主題本身的圖片處理品質差很多,選主題時的速度考量那篇有列出該看哪些訊號。
第三,外掛會互相蓋掉。裝了兩套圖片優化外掛、或是「優化外掛加上快取外掛的 lazy load 功能」同時開啟,非常容易出現「原生 lazy 被 JS lazy 蓋掉」「首圖被誤判成 below-the-fold」這類問題。外掛的疊加成本一向被低估,把站精簡到 11 支外掛的取捨清單裡就有一段在講這種功能重疊。

格式選擇:JPEG、PNG、WebP、AVIF 各自的位置
格式不是「越新越好」,是「這張圖的內容特性適合哪一種編碼」。四種格式的分工其實很清楚,混亂多半來自把它們當成世代關係在看。
先分清楚圖片內容的兩種類型
所有壓縮演算法的差別,最後都可以歸到一個問題:這張圖裡的相鄰像素是連續漸變的,還是有大量銳利邊緣與純色區塊的?
照片屬於前者。天空、皮膚、樹葉的顏色是平滑過渡的,人眼對這種區域的細微失真非常不敏感,所以有損壓縮可以砍掉很多資料而看不太出來。截圖、去背 logo、圖示、含文字的圖屬於後者。它們的特徵是「一個像素是純白、隔壁一個像素是純黑」,有損壓縮在這種邊緣會產生俗稱鬼影或蚊蟲雜訊的模糊暈開,而且非常明顯。
先判斷這一點,格式選擇就只剩下查表。
WebP:現在的預設值
依 Can I Use 的資料,WebP 的全球支援度為 96.15%:Chrome 32+、Edge 18+、Firefox 65+、Safari 16.0+(Safari 14 到 15.6 為部分支援)全部涵蓋,只有 Internet Explorer 完全不支援。以 2026 年的流量結構來說,這個數字代表你可以把 WebP 當成預設值使用,不需要為了那不到 4% 做特別處理——真的要保險,用後面講的 <picture> 降級即可。
省下多少?Google 自家的 WebP 文件給了具體數字:有損 WebP 在相同 SSIM 品質指標下,比同等 JPEG 小 25% 到 34%;無損 WebP 比 PNG 小 26%。透明度方面,無損 WebP 支援 alpha 通道,代價僅為多出 22% 的位元組;而有損 WebP 也支援透明,檔案通常是 PNG 的三分之一。WordPress 官方在 5.8 的公告裡則給了一個較保守的概括說法:「WebP 圖片平均比同等的 JPEG 或 PNG 小約 30%」。
這裡有一個實務上的關鍵:WebP 同時有有損與無損兩種模式。很多人以為 WebP 只能有損,於是去背 logo 還是留在 PNG。實際上無損 WebP 就是用來取代 PNG 的,而且省得比有損取代 JPEG 更確定(26% 是無損對無損的比較,畫質完全不變)。
AVIF:可以上了,但要看你的降級策略
AVIF 的全球支援度依 Can I Use 是 93.42%。分瀏覽器來看:Chrome 85+、Firefox 93+、Safari 16.4+(16.1 到 16.3 為部分支援)、Edge 121+。
那少掉的約 2.7 個百分點是誰?我用 Can I Use 的原始資料逐一比對「支援 WebP 但不支援 AVIF」的瀏覽器版本,答案跟直覺不同:其中約 1.96 個百分點來自 Chrome 85 之前的舊版本,Edge 只佔約 0.30 個百分點,iOS Safari 16 之前約 0.29 個百分點。也就是說,AVIF 真正的缺口不在某一家瀏覽器沒跟上,而在沒有更新的舊裝置——這一群不會因為時間推移就自動消失得很快,所以降級寫法還是要留。
WordPress 從 6.5 起原生支援 AVIF,可以像 JPEG、PNG 一樣直接上傳使用,前提是主機的影像處理函式庫(Imagick 或 LibGD)有編進 AVIF 支援。官方建議的檢查方式很簡單:到 wp-admin 的「工具 → 網站健康狀態 → 資訊」分頁,展開「媒體處理」,看支援格式清單裡有沒有 AVIF。WordPress 官方對 AVIF 的說法是「在維持相同畫質的前提下,可比 JPEG 小上達 50%」,同時支援更廣的色域(含 HDR),在高細節區域比 JPEG 銳利。
我的實務建議是:AVIF 值得用在首圖這種單張、體積大、且是 LCP 元素的位置,用 <picture> 降級到 WebP 再降到 JPEG。全站內文圖全面改 AVIF 的效益比較不明顯,因為 AVIF 的編碼運算成本高很多,批次轉檔會把主機打爆,而且內文圖本來就不大。
picture 元素的降級怎麼寫
MDN 對 <picture> 的規則寫得很清楚:瀏覽器會依序評估每一個 <source> 子元素,挑第一個同時符合媒體條件與支援格式的;如果全部都不符合,或瀏覽器根本不支援 <picture>,就會退回 <img> 的 src。所以順序必須是「最新的格式放最前面」:
<picture>
<source srcset="hero-1600.avif" type="image/avif">
<source srcset="hero-1600.webp" type="image/webp">
<img src="hero-1600.jpg" width="1600" height="900"
alt="說明這張圖在講什麼" fetchpriority="high">
</picture>
注意 width、height、alt、loading、fetchpriority 這些屬性全部寫在 <img> 上,不是寫在 <source> 上。這是最常見的寫錯位置。Google Search Central 的圖片 SEO 文件也特別提醒,用 <picture> 或 srcset 時「務必以 src 屬性指定一個備援網址」。
SVG 與 GIF 的位置
SVG 是向量格式,適合 logo、圖示、簡單的示意圖。它的優勢是無論放大到多少倍都不會糊,而且檔案通常只有幾 KB。缺點是 SVG 本質上是可執行的 XML,可以內嵌 JavaScript——所以 WordPress 預設不允許上傳 SVG,這是安全設計不是疏漏。要開放 SVG 上傳,一定要搭配消毒(sanitize)處理,而且只讓管理員層級上傳。這一塊屬於權限與檔案上傳的安全範疇,可以延伸看WordPress 網站安全的基本功那篇的檔案與權限段落。
GIF 在 2026 年幾乎沒有存在必要。動態 GIF 的檔案大小往往是同等動態 WebP 或短 MP4 的數倍。多數圖片優化外掛都提供「動態 GIF 轉動態 WebP 或 MP4」的功能,這是相當划算的一鍵改善。
Google Search Central 明列 Google 在 <img> 的 src 中支援的格式為:BMP、GIF、JPEG、PNG、WebP、SVG、AVIF。也就是說用新格式不會有索引問題,「怕 Google 讀不到所以不敢換」是過時的顧慮。
格式決策表
| 圖片內容 | 第一選擇 | 降級 | 為什麼 |
|---|---|---|---|
| 照片(人像、風景、產品情境) | WebP 有損 | JPEG | 連續漸變區域,人眼對失真不敏感,省 25 至 34% |
| 首圖或 LCP 大圖 | AVIF | WebP 再降 JPEG | 單張體積最大,值得付編碼成本;用 picture 降級 |
| 去背產品圖、含透明的圖 | WebP 無損或有損 | PNG | WebP 兩種模式都支援 alpha,無損僅多 22% 位元組 |
| 截圖、含文字的說明圖 | PNG 或 WebP 無損 | — | 銳利邊緣,有損會在文字周圍產生明顯雜訊 |
| logo、圖示、簡單示意圖 | SVG | PNG | 向量無限縮放、體積最小;注意上傳前的消毒 |
| 動態圖 | 動態 WebP 或 MP4 | — | 動態 GIF 通常是數倍體積 |
有損與無損:你到底在賣掉什麼
這一節是所有「壓縮率」討論的地基。搞清楚之後,你就不會再問「應該壓到幾成品質」這種沒有唯一答案的問題。
兩者的差別是可逆與不可逆
無損壓縮就像 ZIP:解開之後每一個位元都跟原本一樣。它靠的是找出資料裡的重複模式並用更短的方式表示。所以無損壓縮的效果完全取決於圖片內容——大面積純色的圖可以壓到極小,滿版的細節照片幾乎壓不動。
有損壓縮則是永久丟掉資料。JPEG 的做法大致是把影像切成區塊做頻率轉換,然後把人眼較不敏感的高頻細節量化掉。丟掉的東西回不來——這句話有一個很實際的後果:不要拿已經壓過的圖再壓一次。每一輪有損重壓都會在上一輪的失真上再疊一層,這叫 generation loss。實務上這件事常常在不知不覺中發生:你從別的網站抓一張已經壓過的 JPEG,丟進優化外掛再壓一次,結果就是畫質崩掉而檔案沒省多少。
品質參數怎麼抓:用階梯測試,不要相信通則
網路上流傳的「JPEG 品質設 80 就好」是一個粗略的起點,不是答案。實際的甜蜜點取決於圖片內容:大面積平滑漸層(天空、棚拍白背景)在低品質下就會出現色帶,需要設高一點;雜訊多的實拍照片可以壓得很兇也看不出來。
我實際在用的做法是階梯測試,五分鐘可以跑完:挑三張最有代表性的圖(一張平滑漸層、一張高細節、一張含文字),各自輸出品質 90、80、70、60 四個版本,把檔案大小列出來,然後在螢幕上以 100% 檢視逐一比對。你幾乎一定會看到一個拐點——從 90 掉到 80,檔案小很多而畫質差異看不出來;從 70 掉到 60,檔案沒小多少但畫質明顯崩了。那個拐點就是你這個網站的設定值。設定一次,之後全站沿用。
多數圖片優化外掛會把這件事包裝成三檔(例如有損、中等、無損;ShortPixel 稱為 Lossy、Glossy、Lossless)。選中間那一檔通常就對了,但還是建議你自己看過拐點在哪,因為攝影主導的作品集站與截圖主導的教學站,答案不會一樣。
三種圖不要用有損壓縮
- 含文字的截圖與說明圖:文字邊緣是最不能失真的地方,有損壓縮會讓小字周圍出現一圈髒。
- 去背的 logo 與品牌素材:邊緣鋸齒與半透明像素會被破壞,疊在不同底色上就會露出來。
- 還要再編輯的母檔:母檔一律留無損或原始格式,另外存一份。網站上放的是輸出版本,不是母檔。
metadata 該刪哪些、該留哪些
手機拍的照片會帶 EXIF,裡面可能包含拍攝時間、機型,以及GPS 座標。把一張家裡拍的照片直接上傳到公開網站,等於公開你家的經緯度——這是自架站最常被忽略的隱私問題,尤其是接案者放的工作環境照。
但也不要無腦全刪。ICC 色彩描述檔應該保留,否則在廣色域螢幕上圖片顏色會偏掉(最常見的症狀是照片看起來灰灰的、飽和度不對)。多數優化外掛的 EXIF 設定是「移除 EXIF 但保留色彩描述檔」,那是正確的預設;如果你的圖上線後顏色跑掉,第一個要檢查的就是這個開關被設成全部移除了。
如果你用的是圖庫素材,授權條款有時會要求保留特定的來源資訊,這一點在批次剝除 metadata 之前要先確認。用圖的授權風險是另一個獨立主題,免費圖庫、CC 授權與付費層級的差別那篇有完整整理。用 AI 生成圖的話,輸出尺寸與格式通常可以在生成階段就設對,省掉後面一輪轉檔,AI 圖片生成工具的比較那篇有各家的輸出規格。

尺寸宣告與 CLS:唯一被 Core Web Vitals 直接量測的圖片屬性
如果你今天只做一件事,做這件事。它的成本接近零,效果是可量測的,而且是三項核心指標之一。
CLS 在量什麼
依 web.dev 的官方說明,CLS 量的是「頁面整個生命週期內,所有非預期版面位移中最大的那一叢位移分數」。這裡的「一叢」有明確定義:一連串位移之間間隔小於 1 秒、整叢總長度最多 5 秒,稱為一個 session window。取所有 session window 裡分數最高的那一個當成 CLS。
門檻是:0.1 以下為良好,超過 0.25 為不佳,同樣以第 75 百分位數評估、區分行動與桌機。web.dev 列出的位移成因第一項就是「尺寸未知的圖片或影片」。
該頁面還有一個很值得注意的提醒:開發時已經被快取的圖片,行為跟真實使用者不同。你在自己電腦上重整十次都看不到位移,因為圖片早就在快取裡瞬間出現;真實使用者是第一次載入,圖片要花幾百毫秒才到,那段時間版面就在跳。所以「我看起來沒問題」不是證據,要看實際的欄位資料。要抓真實使用者的數據,Search Console 的 Core Web Vitals 報告是最直接的來源,Search Console 的驗證與基本操作那篇可以先把帳號接起來。
width 與 height 到底做了什麼
MDN 的 <img> 文件寫得很精準:「同時寫上 height 與 width,可以讓瀏覽器在圖片載入之前就算出長寬比。這個長寬比會被用來預留顯示圖片所需的空間,減少甚至完全避免圖片下載並繪製時產生的版面位移。」
關鍵在「載入之前」。沒有這兩個屬性,瀏覽器在 HTML 解析階段完全不知道這張圖多高,只能給它 0 的高度;等圖片真的下載完,才突然撐開,把下面所有東西往下推。那一推就是 CLS。
常見的誤解是「我用 CSS 設了 max-width:100%; height:auto;,所以不用寫 HTML 屬性」。錯了。現代瀏覽器的做法是從 HTML 的 width 與 height 屬性推導出一個內建的 aspect-ratio,再讓 CSS 的 height:auto 依比例撐開。兩者是搭配關係,不是替代關係——HTML 屬性提供比例,CSS 負責響應式縮放。只寫 CSS 的話,瀏覽器仍然不知道比例。
另外,這兩個屬性的數值應該是圖片檔案的原始像素尺寸,不是它在版面上顯示的尺寸。填 1600×900 但實際顯示 760px 寬完全沒問題,瀏覽器要的只是那個 16:9 的比例。
lazy 圖沒有尺寸,比一般圖沒有尺寸更糟
這一段是很多人沒注意到的連鎖效應。MDN 明確警告:「雖然所有圖片都建議明確寫上 width 與 height 屬性以避免版面位移,但對 lazy-load 的圖片尤其重要。」
理由是:lazy-load 的圖片只有在與可視區域產生交集時才會載入,而未載入的圖片其 width 與 height 都是 0。MDN 舉的失效情境是:一張高度為 0 的圖如果沒有和任何可見元素產生交集,就永遠不會被判定進入可視區域,於是永遠不載入;而就算它在別的情況下最後載入了,那個位移也發生在使用者正在閱讀的畫面中間,體驗比載入時就跳一次還糟。
web.dev 的原生 lazy loading 說明頁則記錄了相反方向的另一種失效:沒寫尺寸時圖片預設是 0×0,如果你有一整排相簿圖,瀏覽器會判定它們全部都塞得進可視區域(因為每一張都不佔空間、沒有任何一張被擠出畫面),於是一口氣把整批圖全載下來,反而讓頁面更慢。一個是全都不載、一個是全都載——方向相反,起因同一個:你沒有告訴瀏覽器這張圖多大。
所以「沒寫尺寸加上開了 lazy load」是最壞的組合,而這在裝了 lazy load 外掛卻沒處理尺寸宣告的 WordPress 站上非常普遍。
WordPress 什麼時候會幫你寫、什麼時候不會
好消息是,只要圖片是透過 WordPress 核心的正常路徑輸出(媒體庫插入的圖片區塊、特色圖片、the_content() 過濾後的內容),核心會自動補上 width、height、srcset、sizes,以及後面會講的 loading、decoding、fetchpriority。
壞消息是,以下這些路徑不保證:
- 頁面建構器輸出的圖片模組與背景圖:CSS
background-image根本不是<img>,沒有屬性可寫。首屏的大圖如果是 CSS 背景,你連fetchpriority都加不上去。 - 你自己在文章裡手打的 HTML:包括從別的地方複製貼上的
<img>標籤。 - 被主題或外掛以正則表示式重寫過的內容:某些「圖片延遲載入」外掛會把
src換成data-src,過程中可能連帶弄掉尺寸屬性。 - 輪播、燈箱、相簿類外掛:這些通常用 JavaScript 動態產生標籤。
一個 30 秒的自檢方法
不需要工具。在瀏覽器開啟你的文章頁,按右鍵選「檢視網頁原始碼」(不是「檢查元素」——要看伺服器吐出來的原始 HTML,不是 JavaScript 跑完之後的結果),然後用 Ctrl/Cmd + F 搜尋 <img。逐一看每一個標籤有沒有 width= 與 height=。
三十秒就能知道你的站屬於哪一種:全部都有(核心路徑正常)、部分有(建構器或外掛在搞)、全部沒有(主題把它剝掉了,或整站都是 CSS 背景圖)。這個檢查我在接手每一個網站的第一天都會做,因為它決定了後面要修的是設定還是模板。
srcset 與 sizes:不要讓手機下載桌機的圖
尺寸宣告解決的是版面位移,響應式圖片解決的是傳輸量。兩者是不同的問題,需要不同的屬性。
srcset 提供選項,sizes 告訴瀏覽器要多寬
用 w 描述子的寫法是這樣運作的:srcset 列出「有哪些檔案、各自幾像素寬」,sizes 則描述「在各種視窗寬度下,這張圖在版面上會佔多寬」。瀏覽器把 sizes 算出的 CSS 像素寬度乘上裝置像素比,再從 srcset 挑一個最接近且夠用的檔案。
<img src="photo-1200.webp"
srcset="photo-480.webp 480w,
photo-760.webp 760w,
photo-1200.webp 1200w,
photo-1600.webp 1600w"
sizes="(max-width: 768px) 100vw, 760px"
width="1600" height="900" loading="lazy" decoding="async"
alt="說明這張圖在講什麼">
這裡最容易被誤解的是 sizes。它不是「我希望圖片顯示多大」,而是「請你相信我,這張圖在版面上就是這麼寬」。你寫的值必須跟 CSS 實際算出來的欄寬吻合。
sizes 寫錯的代價比不寫還大
如果你的內文欄寬是 760px,卻寫了 sizes="100vw",那在一台 1440px 寬的桌機上,瀏覽器會以為需要 1440px 寬的圖,於是去挑 1600w 那個檔案——你多下載了一倍的資料,只為了顯示 760px。反過來如果 sizes 寫太小,圖片會糊。
WordPress 核心的預設 sizes 值相當於「(max-width: 圖片寬度) 100vw, 圖片寬度」。這個值在很多主題上是不準的,因為核心不知道你的欄寬。如果你的站有明確固定的內容欄寬,用 wp_calculate_image_sizes 這個過濾器把它改成實際值,是一個一次性、全站受惠的修改。
WordPress 自動產生的 srcset 有哪些邊界
WordPress 自 4.4 起原生支援響應式圖片,會自動在輸出的圖片標籤加上 srcset 與 sizes。要知道的邊界有三個:
srcset只會列出「同一張原圖已經產生出來的子尺寸」。你如果上傳的原圖只有 800px 寬,就不可能有 1600w 可選。這回到第一步:上傳的原圖要夠大(但也不必過大)。max_srcset_image_width過濾器的預設值是 2048px。超過這個寬度的子尺寸不會被放進srcset。- 子尺寸之間的間距太大就沒有意義。如果你的媒體庫只註冊了 300px 與 1024px,那 600px 寬的手機只能選 1024px,等於白做。
sizes 的 auto 值現在能不能用
新的 sizes="auto" 語法可以讓瀏覽器自己依實際版面決定寬度,理論上完全解決前面「寫錯欄寬」的問題。但依 Can I Use 的資料,它目前的全球支援度只有 70.9%:Chrome 126+、Edge 126+、Firefox 150+、Samsung Internet 28+ 支援,而 Safari 與 iOS Safari 至今尚未支援。
因為缺的正好是 iOS 這一大塊,現階段的正確寫法是把它當漸進增強用——寫成 sizes="auto, (max-width: 768px) 100vw, 760px",支援的瀏覽器吃 auto,不支援的退回後面的媒體條件。MDN 的範例就是這樣寫的,而且 auto 依規範只在 loading="lazy" 的圖片上有效。
WordPress 使用者要先知道一件事,免得白工:核心從 6.7 起已經自動在 lazy-load 圖片的 sizes 前面加上 auto,,也就是上面那個漸進增強寫法,核心已經幫你做了(要關掉是 wp_img_tag_add_auto_sizes 過濾器)。所以前面講的「用 wp_calculate_image_sizes 改成實際欄寬」仍然值得做,因為它決定了 auto 失效時(Safari、以及非 lazy 的首圖)退回去用的那組值。
一組實用的尺寸階梯
| 用途 | 建議產出的寬度 | 建議上限檔案大小 | 備註 |
|---|---|---|---|
| 首圖或 LCP 圖 | 760 / 1200 / 1600 | 150 至 200 KB | AVIF 或 WebP;eager 加 fetchpriority high |
| 內文圖 | 480 / 760 / 1200 | 100 KB 以內(理想 30 至 80 KB) | WebP;lazy 加 decoding async |
| 商品列表縮圖 | 200 / 400 | 20 至 40 KB | 數量多,單張省下的量會被倍數放大 |
| logo、圖示 | SVG(不需階梯) | 幾 KB | 向量,無需多尺寸 |
上表的檔案大小是我自己在用的工作上限,不是官方標準——真正該看的還是 LCP 的實測值。電商站的商品圖數量級完全不同,同一頁可能有二十張縮圖,那時候「單張省 15 KB」會變成「整頁省 300 KB」,WooCommerce 的完整開店流程那篇有商品圖尺寸設定的位置。

延遲載入,以及首屏圖為什麼絕對不能 lazy
這一章是本篇最容易做錯、而且做錯會倒扣的部分。
loading 屬性到底做什麼
依 MDN,<img> 的 loading 屬性有兩個值:eager 是預設值,「立即載入圖片,無論它目前是否在可視區域內」;lazy 則是「延後載入,直到圖片接近可視區域一段由瀏覽器決定的距離」。
那個「由瀏覽器決定的距離」不是玄學。web.dev 的說明頁給了 Chrome 的實際門檻:在 4G 連線下,圖片大約在低於可視區域 1,250 像素時開始載入;在 3G 或更慢的連線下,門檻延伸到約 2,500 像素。連線越慢、提前量越大,目的是讓使用者捲到那裡時圖片剛好載完。
這代表一件事:原生 lazy loading 不會讓使用者看到空白框。捲到才載入的那種糟糕體驗,通常是 JavaScript lazy load 外掛的門檻設得太保守造成的,不是原生行為。
首屏圖 lazy 的代價
web.dev 的 LCP 優化文件用了非常罕見的絕對句式:「絕對不要對你的 LCP 圖片使用 lazy-load,那一定會造成不必要的資源載入延遲,並對 LCP 產生負面影響。」
原因很直觀。原生 lazy loading 的判斷需要瀏覽器先完成版面計算,知道這張圖在哪裡,才能決定要不要載。這個「先算版面」的等待,對一張本來就在畫面正中央、應該最優先下載的圖來說,是純粹的浪費。
對應的正解是 fetchpriority="high"。web.dev 的建議是:如果你認為某張 <img> 很可能是頁面的 LCP 元素,就替它設 fetchpriority="high";但同一頁不要設超過一到兩張,設太多等於沒設。
前面提到《Web Almanac 2024》的數字:行動版有 9.5% 的 LCP 圖片元素掛著原生 lazy loading。這個比例高得離譜,而它幾乎都來自「裝了 lazy load 外掛,選了全站套用,沒有排除首圖」。
WordPress 自己怎麼判斷(6.3 之後的邏輯)
WordPress 核心其實把這件事做得比多數外掛好。從 6.3 起,loading 與 fetchpriority 兩個屬性由同一個函式 wp_get_loading_optimization_attributes() 統一決定,邏輯有幾個要點:
- 預設跳過前 3 張圖不加 lazy。這個門檻在 6.3 之前是 1 張,改成 3 是為了配合多欄版面(例如三欄的文章列表,首屏就有三張圖)。
- 面積門檻 50,000 平方像素。核心以寬乘高判斷圖片是否「夠大到值得優先處理」。官方舉的例子是:300×200 的圖符合(60,000),200×200 的圖不符合(40,000)。這個門檻可以用
wp_min_priority_img_pixels過濾器調整。 fetchpriority="high"只加在核心判定「最可能是 LCP」的那一張,也就是可視區域內最大的內容元素。官方引述核心效能團隊的基準測試:替 LCP 圖加上fetchpriority="high",通常可讓 LCP 改善 5% 到 10%。- 已經存在的屬性不會被覆寫。如果在這個函式被呼叫之前,圖片標籤上已經有
loading或fetchpriority,核心會原封不動保留。這給了你手動微調的空間,但也代表某些外掛先手寫死之後,核心的自動判斷就完全失效了。
另外,decoding="async" 自 WordPress 6.1 起就是預設加上的,6.4 之後併入同一個函式統一處理。這個屬性讓瀏覽器可以在主執行緒之外解碼圖片,減少對互動的阻塞——也就是前面提到的 INP 那一環。
WordPress 會判斷錯的四種情況
核心的判斷依賴「圖片在 HTML 裡出現的順序」與「尺寸屬性」,所以以下情況會失準:
- 首圖是 CSS 背景圖。核心看不到它,無法加
fetchpriority。這種情況要在<head>手動放<link rel="preload" as="image" fetchpriority="high">。 - 版面順序與視覺順序不一致。例如側邊欄的圖在 HTML 裡排在正文前面,核心會把「前 3 張」的額度花在你根本看不到的地方。
- 輪播(carousel)。輪播的第二張以後在視覺上不可見,但在 HTML 裡緊接著第一張,核心會把它們也算進前 3 張而不加 lazy。這種情況要手動替第二張之後加上
loading="lazy"。 - 圖片沒有尺寸屬性。面積門檻算不出來,核心就不會判定它是優先圖。這又繞回上一章——尺寸宣告是所有後續自動優化的前提。
不要用 JavaScript lazy load 蓋掉原生
很多快取外掛與優化外掛提供「延遲載入圖片」的選項,做法是把 src 換成 data-src,等 JavaScript 判斷進入可視區域才換回來。這種做法在 2019 年之前有意義,現在多半是負面的:它比原生慢、會讓核心的 loading 與 fetchpriority 邏輯完全失效,而且有索引風險。
Google 的官方文件對延遲載入的要求很明確:內容必須在進入可視區域時就載入,而且不能依賴使用者的捲動或點擊來觸發,理由是「Google 搜尋不會與你的頁面互動」。文件建議的實作方式第一項就是「瀏覽器內建的圖片與 iframe 延遲載入」。驗證方式則是用 Search Console 的網址審查工具,確認算繪後的 HTML 裡 <img> 帶著正確的 src。
我的建議很簡單:把外掛的 lazy load 功能關掉,讓 WordPress 核心處理。除非你的主題或建構器完全繞過核心路徑,否則核心版本比外掛版本正確得多。
WordPress 端怎麼實作:媒體庫、big_image_size_threshold 與三條路線
前面的原則講完,這一章是實際的操作面。
上傳前就該做的一件事
最有效的一步發生在你按下上傳之前:把原圖縮到你實際需要的最大寬度。內文欄寬 760px、要支援 2 倍解析度螢幕,那 1600px 就非常夠了。從 4032px 縮到 1600px,資料量減少到大約六分之一,而且是無損於顯示品質的減少——因為那些多出來的像素本來就沒有機會被顯示。
這一步用 macOS 內建的預覽程式、Windows 的小畫家、或任何一個線上工具都能做。它不需要外掛、不消耗主機資源、也不會有相容性問題。我把它排在所有步驟的第一位,是因為它同時降低了後面每一個步驟的成本:更小的原圖、更快的子尺寸產生、更少的備份體積、更低的 CDN 傳輸量。
big_image_size_threshold:那個 -scaled 檔案是怎麼來的
如果你曾經在 uploads 資料夾看到檔名結尾是 -scaled.jpg 的檔案,那就是這個機制。
WordPress 從 5.3 起加入了「大圖處理」:當你上傳的圖片寬度或高度超過門檻時,核心會產生一個縮到門檻大小的版本,並把它當成之後所有場合使用的「完整尺寸」;原始檔案仍然保留,但不會被前台使用。這個門檻的預設值是 2560 像素,同時當作最大寬與最大高。
控制它的是 big_image_size_threshold 過濾器。要完全停用自動縮放:
add_filter( 'big_image_size_threshold', '__return_false' );
要改成別的值(例如你確定站上永遠不需要超過 1600px):
add_filter( 'big_image_size_threshold', function() { return 1600; } );
我的看法是:多數自架站應該把它調低,而不是停用。2560px 對內容型網站太大了,它的存在是為了涵蓋攝影作品集這類需求。調到 1600 或 2048,等於幫你架了一道防呆——就算哪天你或客戶忘了先縮圖,核心也會擋下來。注意這個設定只對「之後上傳的圖片」生效,已經在媒體庫裡的要另外用重新產生縮圖的工具處理。
媒體庫尺寸設定:每註冊一個尺寸就多一份檔案
WordPress 預設會為每張上傳的圖產生數個子尺寸。除了設定頁上看得到的縮圖(預設 150×150)、中(300)、大(1024),還有幾個不在設定頁上的:medium_large 預設寬 768px、不限高度;以及 5.3 加入的 1536×1536 與 2048×2048,用途是讓高密度螢幕能挑到更合適的 srcset 來源,不必回頭用未經優化的原圖。
再加上佈景主題與外掛用 add_image_size() 註冊的自訂尺寸——一個電商主題註冊七、八個尺寸是很常見的——你上傳一張圖,磁碟上可能就多出十幾個檔案。這件事有兩個後果:備份體積膨脹,以及轉檔外掛的額度消耗暴增(多數外掛是按「處理的圖片張數」計費,子尺寸每一張都算一次)。
實務上的做法是:進外掛的設定,把用不到的子尺寸排除在優化範圍外。多數圖片優化外掛都有逐一子尺寸控制這類選項,可以勾選要處理哪些尺寸。這一個設定常常就能把你的額度消耗砍半。備份體積的問題則屬於另一條線,三層備份策略那篇有講到 uploads 資料夾該怎麼分開處理。
WordPress 不會自動幫你轉 WebP
這是最多人誤解的一點,值得單獨講清楚。
WordPress 5.8 加入的是「可以上傳並使用 WebP」,不是「自動把 JPEG 轉成 WebP」。官方公告寫得很明白:預設情況下,核心產生的子尺寸會沿用你上傳檔案的格式,JPEG 上傳就還是 JPEG。
核心團隊確實推過「WebP by default」的提案,計畫在 6.1 讓核心自動為 JPEG 產生 WebP 版本。但那個變更在 2022 年 9 月被回退,沒有進入 6.1,理由包括儲存空間翻倍、以及作業系統對 WebP 的處理當時仍不順暢。後續改以功能外掛的形式讓使用者自行選用。
6.5 加入的 AVIF 支援也是同樣性質:可以上傳與使用,但不會自動轉換,原始上傳檔案一律保留以便日後重新編輯或重新產生。想讓核心在產生子尺寸時輸出成別的格式,官方指出的方式是 image_editor_output_format 過濾器。
結論:要全站 WebP 或 AVIF,你一定需要外掛、主機端功能或 CDN 其中之一。這就是下一節。
三條路線:外掛、主機端、CDN
| 路線 | 怎麼運作 | 優點 | 要注意的地方 |
|---|---|---|---|
| 外掛(ShortPixel、Imagify、EWWW 等) | 上傳時或批次把媒體庫的檔案壓縮、額外產生 WebP 或 AVIF 版本,前台改送新格式 | 設定直覺、可逐張控制、換主機也帶得走 | 吃主機 CPU(或走廠商 API);多按張數計費,子尺寸會放大消耗;換掉外掛時要確認新格式檔案怎麼處理 |
| 主機端(託管型 WordPress 主機內建) | 由主機在傳送層自動轉檔與最佳化,網站本身不需要任何設定 | 零維護、不吃網站的 PHP 資源 | 綁定該主機,搬家就沒了;可控性最低;不是每家都有 |
| CDN(Cloudflare Images、Bunny、Cloudinary 等) | 圖片由邊緣節點依請求端支援度即時轉檔並快取,原站只留一份原圖 | 不動媒體庫、可依裝置即時產生尺寸、同時解決全球延遲 | 按傳送量或轉換次數計費;要處理來源網址與 image sitemap;設定門檻最高 |
我的判準是這樣:一般內容型自架站選外掛,成本可控、可攜性好。已經在用託管型主機的,先看主機有沒有內建,有的話不要再疊外掛。主機的選型本身牽涉到共享、VPS、託管型的取捨與續約陷阱,主機怎麼選那篇已經拆得很細,這裡就不重複。圖片量非常大、或使用者分散在多國的站才需要 CDN 路線——大部分以台灣本地讀者為主的部落格,用不到那個複雜度。
費用怎麼看(查核日 2026 年 8 月 2 日)
價格與額度是會變的東西,以下數字都以查核當天的官方定價頁為準,做決定前請自己再開一次確認。
- Imagify:免費方案為每月 20 MB 的處理額度(官方標示約 200 張圖)。付費的 Growth 方案為每月 500 MB(約 5,000 張),月付 5.99 美元,改年繳後均攤為每月 4.99 美元;Infinite 方案為不限額度,月付 11.99 美元,年繳均攤每月 9.99 美元。所有方案皆不限網站數。(官方定價頁)
- ShortPixel:定價以點數(credits)計算,官方頁面同時提供每月訂閱與一次性購買兩種模式,實際級距與金額由頁面上的滑桿決定,這裡不轉述數字,請以官方定價頁為準。功能面官方明列包含有損、Glossy、無損三種演算法、自動轉換 WebP 與 AVIF、動態 GIF 轉動態 WebP 或 MP4、EXIF 管理、逐一子尺寸控制與 WP-CLI 支援。
- Cloudflare Images:免費方案每月可請求最多 5,000 次不重複轉換,超過就回傳錯誤且不計費。付費方案為前 5,000 次不重複轉換內含,之後每 1,000 次每月 0.50 美元;儲存為每 10 萬張每月 5 美元;傳送為每 10 萬張每月 1 美元。(官方定價文件)
一個常被忽略的成本:按張數計費的外掛,實際消耗是「原圖張數乘上子尺寸數量」。如果你的主題註冊了八個尺寸,上傳 500 張圖就是 4,500 次處理(含原圖),免費額度會在你還沒搞清楚狀況之前就用完。先去外掛設定把用不到的尺寸排除,再開始批次處理。
alt 文字怎麼寫:不是塞關鍵字,也不是描述每一個細節
alt 文字有兩個讀者:使用螢幕報讀器的人,以及 Google。好消息是這兩者要的東西高度重疊;壞消息是多數人寫的是第三種東西——關鍵字。
Google 官方的好壞範例
Google Search Central 的圖片 SEO 文件說得很直接:在提供圖片的中繼資料上,alt 是最重要的屬性。它給的四級範例值得逐一對照:
- 最差(完全沒有):
<img src="puppy.jpg"/> - 很差(關鍵字堆砌):把 alt 塞成「puppy dog baby dog pup pups puppies」這類重複詞串
- 比較好:
alt="puppy" - 最好:
alt="Dalmatian puppy playing fetch"
差別在哪?「最好」那一版描述的是這張圖裡發生了什麼事——什麼品種的狗、在做什麼。它自然而然帶到了關鍵字,但因為是在真的描述圖片,所以不構成堆砌。Google 給的原則是「專注在創造有用、資訊豐富的內容,適當地使用關鍵字並保持在脈絡裡」。
換成中文的實例,同一張圖:
- 不合格:
alt="網站圖片優化 圖片壓縮 WebP 轉檔 WordPress 圖片"(堆砌,而且對報讀器使用者是噪音) - 不合格:
alt="圖片"(沒有資訊) - 合格:
alt="媒體庫設定頁的圖片尺寸欄位,縮圖設定為 150 像素"(真的在描述)
三個中文站特有的實務問題
長度。中文的資訊密度比英文高很多,同樣的意思用中文寫大約只要一半的字元。我的工作上限是 50 個漢字,超過就代表你在描述細節而不是主體。螢幕報讀器會把 alt 一字不漏念出來,太長是折磨。
裝飾性圖片。分隔線、純背景、純裝飾的插圖應該用 alt=""(空字串,但屬性要留著),讓報讀器直接跳過。不要把屬性整個刪掉——沒有 alt 屬性時,某些報讀器會退而念出檔名,那通常比沒有更糟。空 alt 與沒有 alt 在無障礙上是完全不同的兩件事。
檔名不要用中文。中文檔名會被轉成百分號編碼,變成一長串亂碼網址,在某些 CDN 與快取層還可能直接壞掉。Google 的建議是檔名要「簡短但具描述性」,官方對比是 my-new-black-kitten.jpg 優於 IMG00023.JPG,並要避免 image1.jpg、pic.gif 這種通用命名。所以規則是:小寫英文、連字號分隔、2 到 5 個描述字、關鍵字前置。
圖說與 alt 不要寫成同一句
圖說(<figcaption>)是給所有人看的補充說明,alt 是給看不到圖的人的替代描述。兩者功能不同,內容也不該一樣。實務上的分工是:alt 描述「圖裡有什麼」,圖說補充「為什麼要看這張圖」。如果你把同一句話複製到兩個地方,螢幕報讀器的使用者會連續聽到兩次相同的內容。
image sitemap 什麼時候需要
Google 的文件指出,可以透過提交 image sitemap 來提供「我們可能無法用其他方式發現的圖片網址」,並特別提到這在使用 CDN 時特別有用,因為 sitemap 裡可以包含其他網域的網址。
換句話說:圖片都放在自己網域、且都以正常 <img> 輸出的站,通常不需要特別處理(Rank Math、Yoast 這類 SEO 外掛預設就會把圖片納入 sitemap)。把圖片外掛到 CDN 網域之後,就要回頭確認 sitemap 有沒有跟著更新。這是換 CDN 之後圖片搜尋流量掉光的常見原因。
無障礙的部分只到這裡
alt 文字只是無障礙的一小塊,而且是最容易的一塊。對比度、鍵盤操作、焦點樣式、表單標籤、標題階層這些同樣屬於 WCAG 的基本要求,而且在中文站上有一些額外的坑。網站無障礙設計的 WCAG 重點與八個常見問題那篇把整套講完了,包括台灣的無障礙規範現況與覆蓋層外掛為什麼被身障社群反對。本篇就不重複那一段。
順帶一提《Web Almanac 2024》的一個數字:行動版只有 55% 的圖片具有非空白的 alt 屬性。也就是說接近一半的圖片,在報讀器使用者那邊是不存在的。這是一個投入極小、缺口極大的位置。
一份可以照著跑的檢查順序
把前面所有東西收成一份清單。分成三個階段,不要一次做完。
階段一:盤點(約 30 分鐘)。
- 用 PageSpeed Insights 或 Search Console 的 Core Web Vitals 報告,記下三個頁面類型(首頁、文章頁、列表頁)目前的 LCP 與 CLS。這是基準線,沒有它你之後不會知道改善了多少。
- 在文章頁按右鍵「檢視網頁原始碼」,搜尋
<img,確認尺寸屬性的覆蓋率。 - 確認首屏那張圖有沒有被加上
loading="lazy"。這是最常見也最傷的錯誤。 - 到「工具 → 網站健康狀態 → 資訊 → 媒體處理」,看主機支援哪些格式(WebP、AVIF)。
- 看一下 uploads 資料夾的總體積,以及媒體庫最大的那幾張圖有多大。
階段二:止血(約 1 小時)。
- 設定
big_image_size_threshold為 1600 或 2048,避免之後再有超大圖進來。 - 關掉所有外掛的 JavaScript lazy load 功能,讓 WordPress 核心接手。
- 確認首圖沒有 lazy、且帶有
fetchpriority="high"(核心通常會處理;建構器做的首圖要手動確認)。 - 如果首圖是 CSS 背景圖,改成
<img>,或在<head>加上對應的 preload。 - 找出尺寸屬性缺失的來源(主題模板、建構器、手打 HTML),逐一補上。
階段三:轉檔與批次處理(視媒體庫大小,數小時到數天)。
- 選定一條路線(外掛、主機端或 CDN),先只裝一個,不要疊加。
- 進外掛設定,排除用不到的子尺寸,避免額度被子尺寸吃光。
- 做階梯測試決定壓縮強度,設定 EXIF 為「移除但保留色彩描述檔」。
- 先備份 uploads 資料夾,再開始批次轉檔。多數外掛會保留原檔,但這一步不能省。
- 批次跑完後,抽查十張不同類型的圖(照片、截圖、去背圖)目視確認畫質,特別看文字周圍與去背邊緣。
- 兩到四週後回頭看 Search Console 的 Core Web Vitals 報告——那是真實使用者資料,需要時間累積。
整個站的圖片優化,如果你只有一個下午,做完階段一與階段二就好。那兩個階段是零費用的,而且處理掉的是最傷的幾個錯誤。階段三是錦上添花,可以慢慢來。
如果你的網站還在規劃階段、根本還沒有圖片問題,那更好——把上面的規則寫進工作流程,之後就不會有需要回頭補的一天。從零開始的整體決策順序,網站架設新手指南那篇有完整的路線圖。
常見問題
已經上線幾百篇的舊圖,要不要全部重新轉檔?
不用一次全做,而且優先順序應該由流量決定,不是由發布日期決定。做法是:打開 Search Console 或 GA4,抓出流量前 20 的頁面,只處理那些頁面上的圖。這 20 頁通常佔掉你大半的自然流量,改完就吃到大部分的效益。剩下的長尾頁面用外掛的批次功能在背景慢慢跑就好,反正沒人在等。要注意的是批次轉檔會吃掉大量主機資源,共享主機請在離峰時段跑,而且務必先備份 uploads。
裝了圖片優化外掛,PageSpeed 還是說「以新世代格式提供圖片」,為什麼?
最常見的三個原因。第一,外掛產生了 WebP 檔案,但前台送出的還是舊格式——通常是伺服器的重寫規則沒生效,或是快取外掛把舊的 HTML 快取住了,清一次快取再測。第二,被點名的圖不是媒體庫的圖,而是主題或外掛自帶的圖(例如佈景主題內建的裝飾圖、外掛的圖示),這些不在媒體庫裡,優化外掛掃不到。第三,被點名的是 CSS background-image,多數外掛只處理 <img>。用瀏覽器開發者工具的 Network 分頁看那個檔案的實際回應格式,三種原因很快就能分辨出來。
AVIF 現在可以全站直接換掉嗎?
全球支援度依 Can I Use 是 93.42%,數字看起來夠,但我不建議全站無降級直接換。缺口主要來自沒有更新的舊裝置(比對 Can I Use 原始資料,缺的 2.7 個百分點裡約 1.96 點是 Chrome 85 之前的舊版),這一群不會很快消失。務實的做法是:首圖這種單張大圖用 AVIF 並以 <picture> 降級到 WebP 再到 JPEG,內文圖維持 WebP 就好。另外要確認主機的影像處理函式庫有 AVIF 支援(工具 → 網站健康狀態 → 資訊 → 媒體處理),沒有的話 WordPress 6.5 之後的原生支援也用不上,這時候 CDN 路線反而比較單純,因為轉檔發生在邊緣節點而不是你的主機。
圖片要壓到多小才算夠?
沒有一個放諸四海的數字,因為「夠不夠」的判準是 LCP 有沒有進 2.5 秒,而那同時取決於你的主機、CDN、以及使用者的網路。我自己在用的工作上限是首圖 150 到 200 KB、內文圖 100 KB 以內,但那是經驗值不是標準。比較可靠的做法是反過來推:先用 PageSpeed Insights 測出目前的 LCP,把首圖砍到一半再測一次,看曲線動多少。如果砍一半只讓 LCP 快了 80 毫秒,那瓶頸根本不在圖片,你應該去看 JavaScript 或伺服器回應時間。
用 CSS 背景圖是不是就不用管這些了?
正好相反,CSS 背景圖是更難處理的情況。它不是 <img>,所以沒有 alt(無障礙上等於不存在)、沒有 srcset(要自己用 media query 硬寫多組)、沒有 loading 與 fetchpriority(WordPress 核心的自動優化完全套不上)、也不會被 image sitemap 收錄。它唯一適合的場合是純裝飾——本來就不該有替代文字、也不需要被搜尋到的紋理或漸層。只要那張圖承載了任何資訊或是頁面的主視覺,就應該是 <img>。首屏的大圖如果因為版型限制非得用背景圖,記得在 <head> 補上 <link rel="preload" as="image" fetchpriority="high">,否則 LCP 一定難看。
資料來源
- web.dev — Web Vitals(LCP 2.5 秒、INP 200 毫秒、CLS 0.1 與第 75 百分位數的評估方式)
- web.dev — Cumulative Layout Shift(session window 定義、0.1 與 0.25 門檻、位移成因)
- web.dev — Optimize Largest Contentful Paint(絕不 lazy-load LCP 圖片、fetchpriority 的使用限度)
- web.dev — Browser-level image lazy loading(Chrome 的 1,250 與 2,500 像素門檻、尺寸屬性的必要性)
- MDN — img 元素(loading、width 與 height 的長寬比作用、lazy 圖尺寸為 0 的警告、sizes 範例)
- MDN — picture 元素(來源評估順序與 img 備援規則)
- Can I Use — WebP 支援度(96.15%)
- Can I Use — AVIF 支援度(93.42%、Edge 121+)
- Can I Use — sizes 屬性的 auto 值支援度(70.9%,Safari 未支援)
- WebP 與 AVIF 支援度差距的逐瀏覽器拆解(Chrome 舊版 1.96 點、Edge 0.30 點、iOS Safari 0.29 點),是我以 Can I Use 公開資料集逐版本比對後自行計算的,不是 Can I Use 頁面上直接標示的數字。
- Google Search Central — Google 圖片 SEO 最佳做法(alt 範例、檔名、image sitemap、支援格式)
- Google Search Central — 延遲載入內容的正確做法
- Google — WebP 官方說明(有損比 JPEG 小 25 至 34%、無損比 PNG 小 26%、透明度成本)
- Make WordPress Core — WordPress 5.8 加入 WebP 支援
- Make WordPress Core — WebP by default 於 6.1 前被回退
- Make WordPress Core — WordPress 6.5 加入 AVIF 支援
- Make WordPress Core — WordPress 6.3 的圖片效能改善(前 3 張、50,000 平方像素門檻、fetchpriority 改善 LCP 5 至 10%)
- Make WordPress Core — WordPress 5.3 的大圖處理機制
- WordPress Developer — big_image_size_threshold(預設 2560px)
- WordPress Developer — 響應式圖片 API(4.4 起、medium_large 768px、max_srcset_image_width 預設 2048)
- Make WordPress Core — WordPress 6.7 為 lazy-load 圖片自動加上 sizes=”auto”(預設 sizes 為「(max-width: 圖片寬度) 100vw, 圖片寬度」)
- WordPress Developer — _wp_add_additional_image_sizes()(5.3 起新增 1536×1536 與 2048×2048 子尺寸)
- WordPress Developer — wp_omit_loading_attr_threshold(預設 3;6.3 由 1 改為 3)
- HTTP Archive Web Almanac 2024 — 媒體章節(尺寸屬性 32%、LCP 圖 lazy 9.5%、WebP 12% 與 AVIF 1.0%、alt 55%)
- HTTP Archive Web Almanac 2024 — 頁面重量章節(各類資源的中位數位元組)







