同一張圖片,27 吋高解析螢幕跟一支用 4G 連線的舊安卓手機,需要的檔案大小差了不只十倍。如果你的 WordPress 把同一張 1500px 寬的大圖原封不動丟給兩邊,手機讀者就得多載好幾百 KB 用不到的像素,頁面變慢、LCP(最大內容繪製)分數變差,連帶吃掉行動端的搜尋排名。
WordPress 從 4.4 版開始就內建了 srcset 與 sizes 兩個屬性,理論上會自動讓瀏覽器挑對尺寸。但「內建」不等於「裝好就最佳」。預設值偏保守、sizes 算錯、主題沒接好、改了尺寸卻沒重新產生縮圖,都會讓手機照樣載到桌機大圖。這篇把整套機制拆開講清楚:WordPress 到底自動做了什麼、哪幾個環節最常出包、以及你該在哪裡動手調整、哪裡放著不要碰。
WordPress 的 srcset 是怎麼自動運作的
簡單說,srcset 是一份「同一張圖的不同尺寸清單」,sizes 則告訴瀏覽器「這張圖在版面上實際會佔多寬」,瀏覽器拿這兩個資訊自己挑一張最省又夠清晰的檔案下載。整個過程發生在瀏覽器端,伺服器只是把選項一次送過去。
當你把圖片上傳到媒體庫,WordPress 會自動裁切出好幾個尺寸版本。預設這幾組:
- 縮圖(thumbnail):150×150,硬裁切
- 中(medium):最長邊 300px
- 中大(medium_large):寬 768px,這是 4.4 為了響應式特別新增的尺寸
- 大(large):最長邊 1024px
- 完整尺寸(full):你上傳的原圖
接著只要圖片是透過區塊編輯器、古典編輯器,或主題用 the_post_thumbnail()、wp_get_attachment_image() 這類函式輸出,WordPress 就會自動把這份清單寫成 srcset,並補上一個 sizes 屬性。最後產出的 HTML 大概長這樣:
<img src="image-1024x683.jpg"
srcset="image-300x200.jpg 300w,
image-768x512.jpg 768w,
image-1024x683.jpg 1024w"
sizes="(max-width: 600px) 100vw, (max-width: 1024px) 768px, 1024px"
alt="圖片說明文字">
srcset 裡每個檔名後面的 300w、768w 是該檔案的實際像素寬度(不是顯示寬度)。瀏覽器把這些寬度,對照 sizes 算出來的「預計顯示寬度」再乘上螢幕的像素密度,挑出剛好夠用的那一張。這就是為什麼正常情況下手機會載到 medium 或 medium_large,而不是 full。
要注意一個前提:如果你在內容裡貼的 HTML 已經自己寫了 srcset 或 sizes,WordPress 不會去覆蓋它。這個機制只對「由 WordPress 產出的圖片標記」生效。
為什麼預設的 sizes 屬性常常算錯
問題幾乎都出在 sizes 這一邊,而不是 srcset。srcset 只是把所有現成尺寸列出來,WordPress 列得相當完整;真正容易出錯的是 sizes,因為它得「猜」圖片在版面上會佔多寬,而 WordPress 在輸出 HTML 的當下,根本不知道你的主題版型長怎樣。
WordPress 的預設 sizes 值等同於 (max-width: {圖片寬度}px) 100vw, {圖片寬度}px。白話講就是:「視窗比這張圖窄的時候,圖片佔滿整個視窗寬度(100vw);比這張圖寬的時候,就固定用圖片自己的寬度。」
這個預設在「圖片真的會佔滿內容區、而內容區又等於視窗寬」時沒問題。但實際版面常常不是這樣:
- 側邊欄的縮圖:可能只佔 300px 寬,瀏覽器卻被 100vw 告知「你會佔滿整個視窗」,於是在桌機上抓了一張遠大於 300px 的圖。
- 置中內文圖:很多主題內容區只有 700~800px,圖片再寬也不會超過這個範圍,但預設 sizes 仍可能讓瀏覽器以為要塞滿視窗。
- 多欄網格、相片牆:一張圖只佔欄寬的三分之一,預設值完全沒反映這件事。
換句話說,sizes 算錯時,瀏覽器並沒有壞掉,它只是「照你給的錯誤資訊」忠實地挑了一張過大的圖。手機載到桌機大圖,十之八九是這裡出問題。
內容區寬度與 srcset 上限的關係
要判斷 WordPress 給的尺寸合不合理,得先知道兩個會限制上限的設定。
第一個是主題的內容寬度($content_width)。這個變數定義了內容區能放多寬的圖,也會影響 WordPress 在計算響應式圖片時的參考值。如果你的主題把它設成 700px,那麼放在內文的圖片實際顯示寬度就被這個值框住;了解這個數字,你才有辦法寫出貼近版面的 sizes。
第二個是 srcset 的最大寬度上限。WordPress 提供 max_srcset_image_width 這個篩選器(filter),用來限制能被列進 srcset 的圖片寬度,避免把超大原圖塞進清單。早期社群討論常見的數字是 1600px,目前版本的預設值是 2048px。多數情況不需要動它;只有當你刻意要把更大的圖(例如全螢幕背景)納入候選時,才需要透過篩選器把上限調高。
了解這兩個上限的意義在於:當你發現某張圖怎麼樣都載不到夠大的版本(在大螢幕上看起來糊),問題可能是 srcset 上限卡住或原圖根本沒那麼大;而當手機載到過大的圖,問題通常在 sizes 算太寬,跟上限無關。先分清楚是哪一種,才不會亂調。
WordPress 6.7 的 sizes=auto 解決了什麼
如果你的站跑在 WordPress 6.7 以後,有一個新機制大幅減少了 sizes 算錯的機會:針對延遲載入(lazy loading)的圖片,瀏覽器可以直接用「實際算出來的版面寬度」去挑 srcset,不必再靠 WordPress 事先猜。
原理是延遲載入的圖片本來就不會在頁面一開始就下載,要等捲動接近時才載——這時候版面早就算好了,瀏覽器知道這張圖實際會顯示多寬。HTML 規格新增的 sizes="auto" 就是讓瀏覽器在這個時間點用真實的版面寬度來選圖,結果幾乎是 100% 正確,浪費的位元組大幅減少。
WordPress 6.7 的做法是:當圖片帶有 loading="lazy" 時,自動在 sizes 值前面加上 auto,變成 auto, (原本的 sizes 清單)。不支援這個新值的舊瀏覽器會自動忽略 auto、退回使用後面那串原本的 sizes,所以是漸進增強(progressive enhancement),不會把舊瀏覽器搞壞。
這裡有個關鍵限制要記住:WordPress 只在圖片是 loading="lazy" 時才加 auto。如果你用了某些外掛或自訂程式,在 WordPress 產生標記之後才去改 loading 屬性,順序錯開就會讓 sizes 失效,反而退回 100vw 載到過大的圖。遇到這種狀況,正確做法是改用 wp_img_tag_add_auto_sizes() 這個函式去補回 auto。
實務上,多數人升級到 6.7 之後,sizes 算錯的老問題會自己緩解一大半,前提是圖片有正常啟用延遲載入。
怎麼檢查瀏覽器到底載到哪張圖
在動手調設定之前,先學會診斷,不然你根本不知道有沒有問題、改了有沒有效。最快的方法不需要任何外掛。
在你的網站文章頁上對著圖片按右鍵,選「檢查」打開開發者工具,看那個 <img> 標籤:
- 有沒有 srcset:如果只有一個
src、完全沒有 srcset,代表你的主題沒接響應式圖片(通常是 4.4 之前的老主題,或自訂輸出圖片時繞過了核心邏輯)。這種要先處理主題。 - srcset 列了哪些尺寸:確認 medium、medium_large、large 這些版本都在清單裡。少了某個尺寸,多半是改過尺寸設定卻沒重新產生縮圖。
- sizes 寫了什麼:如果是死板的
100vw或一個遠大於實際版面的固定值,那就是 sizes 沒調好。
接著切到開發者工具的「Network(網路)」分頁,把畫面縮到手機寬度重新整理,看那張圖實際下載的是哪一個檔名、多大。如果手機寬度下還在抓 -1024x 甚至原圖,就確定是 sizes 或載入順序的問題。記得把瀏覽器分頁的「Disable cache(停用快取)」勾起來再測,不然舊的大圖被快取住,會讓你誤判已經修好的設定還是壞的。
這套右鍵檢查 + Network 觀察,是後面所有調整的驗收標準:改完一定回來重看一次,確認手機寬度真的載到較小的檔案。
該調整哪裡,哪裡放著不要碰
釐清問題後,依狀況選對應的做法,不要一次全改。
狀況一、sizes 算太寬,手機載到過大的圖
這是最常見的。如果你的站已經是 6.7 以後、圖片也有延遲載入,先確認 sizes 開頭有沒有 auto,有的話通常就交給瀏覽器處理了。若還是不對,或你的版型有固定的內容寬度,就用 wp_calculate_image_sizes 篩選器在主題的 functions.php 裡覆寫 sizes,讓它反映真實版面。例如內容區固定 720px、圖片置中,sizes 寫成 (max-width: 720px) 100vw, 720px 就比預設貼近實際。側邊欄縮圖、網格圖則各自給對應的窄值。
狀況二、srcset 清單缺尺寸,或想多一個剛好的尺寸
如果現成的 medium(300)和 medium_large(768)之間落差太大,瀏覽器在某些寬度只能往上抓 768,可以用 add_image_size() 註冊一個中間尺寸(例如 480 或 600px 寬),補進候選清單。註冊新尺寸要掛在 after_setup_theme 階段,而且只對「之後上傳的新圖」生效。
狀況三、改過尺寸設定,但舊圖沒變
WordPress 不會在你改設定後自動把舊圖重新裁一遍。改了 add_image_size() 或調整媒體設定裡的尺寸,得用 Regenerate Thumbnails 這類外掛,到工具選單按「重新產生所有附件的縮圖」,舊圖才會補出新尺寸版本。順序很重要:先在程式碼註冊好尺寸,再去重新產生,不然會產不出你要的那一檔。
狀況四、想在手機跟桌機顯示「不同構圖」的圖
這已經超出 srcset 的範圍。srcset 處理的是「同一張圖的不同尺寸」,不能換構圖或裁切比例;不同瀏覽器在這件事上的行為也不完全一致,有些會偏好已經快取的較大檔案。如果你真的需要手機顯示直式特寫、桌機顯示橫式全景,要改用 <picture> 元素搭配 <source> 明確指定不同條件載不同檔案,而不是硬塞進 srcset。
哪裡放著不要碰:max_srcset_image_width 上限、medium_large 的寬度、核心自動產生的 srcset 邏輯,這些在沒有明確問題時都不要動。它們是讓多數網站「裝好就堪用」的安全網,沒事去改只會引入難查的副作用。
srcset 之外,還有兩件事會拖慢圖片
把 srcset 跟 sizes 調對,只解決了「載對尺寸」這一半。還有兩個常被忽略的環節。
第一是壓縮。WordPress 會幫你產生多種尺寸,但不會壓縮它們——每個尺寸版本都用你上傳原圖的同一個品質存著。換句話說,就算瀏覽器挑到了正確的中尺寸,那個檔案本身可能還是沒壓過、偏肥。這部分要靠圖片壓縮外掛把所有尺寸版本一起處理,而不只壓原圖。先把格式(例如改用 WebP)跟品質設定弄對,再談 srcset 才有意義。
第二是高解析度(retina)螢幕。前面講的都是依視窗寬度選圖,但 2x、3x 的高密度螢幕還會額外要求兩倍像素的版本來維持清晰。WordPress 預設不會幫你產生 2x 變體,所以在 retina 螢幕上,原本剛好的圖可能被放大而略顯模糊。需要的話得靠專門產生 2x 變體並把它們加進 srcset 的外掛來補。要留意 2x 檔案明顯比標準版大,務必連同壓縮一起處理,不然又繞回「檔案太肥」的老問題。
另外別漏掉 width 與 height 屬性。圖片標記上要帶寬高,瀏覽器才能在圖還沒載完時先預留空間,避免版面位移(這也是 Core Web Vitals 的一項指標)。透過媒體庫上傳的圖,WordPress 會自動帶上;但如果你是手刻 HTML 或用自訂程式輸出圖片,記得自己補上寬高兩個屬性。
把響應式圖片真正調到位的順序
WordPress 的響應式圖片不是壞,是「預設保守、沒人驗收」。它幫你把 srcset 清單列得很全,但 sizes 怎麼算、主題有沒有接好、改了尺寸有沒有重新產生、檔案有沒有壓過,這些它管不到,得你自己收尾。
建議的執行順序是:先右鍵檢查現況,確認 srcset 有出現、看 sizes 寫了什麼、用 Network 分頁實測手機寬度載到哪一檔;升級到 6.7 以上讓延遲載入的圖吃到 sizes=auto;真的算不準再用 wp_calculate_image_sizes 依你的內容寬度覆寫;尺寸有缺口才 add_image_size() 補,補完記得重新產生縮圖;最後把壓縮跟(必要時)retina 變體補上。每改一步都回到開發者工具重看一次,確認手機真的載到較小的檔案,才算數。動手之前先量、改完之後再驗,別讓手機讀者繼續默默幫你下載用不到的桌機大圖。