跳至內容
圖片與媒體

如何關閉 WordPress 的 -scaled 圖片(big_image_size_threshold)

用 big_image_size_threshold 篩選器提高或移除 2560px 上限,修好糊掉的 WordPress 圖片,並看懂大家最常漏掉的那一步:重新上傳。

發布於

big_image_size_threshold 上掛一個回傳 false 的篩選器,WordPress 就不會在上傳時建立 -scaled 副本。改成回傳一個數字,則是把上限調高而不是移除。兩種寫法都放在 functions.php 或一個小型的 mu-plugin 裡,也都只影響篩選器生效之後才上傳的圖片。

// Disable the cap entirely — no -scaled copies at all.
add_filter( 'big_image_size_threshold', '__return_false' );
// Or just raise it. Longest edge, in pixels.
add_filter( 'big_image_size_threshold', function () {
    return 3840;
} );

WordPress 實際上在做什麼

從 WordPress 5.3 開始,每一張上傳的圖片都會被量測最長邊。如果那一邊大於 big_image_size_threshold(預設是 2560px),WordPress 會把圖片重新編碼縮到這個上限,存成 your-photo-scaled.jpg,並改寫附件中繼資料,讓 full 尺寸從此指向這份縮小的副本。

你的原始檔不會被刪除。它會以原本的檔名留在磁碟上,也記錄在附件中繼資料裡,在 PHP 裡可以透過 wp_get_original_image_path() 取得。但前台不會有任何地方送出它。區塊編輯器不會、srcset 不會、媒體庫預覽也不會。它就只是躺在那裡,當一份存檔。

之後所有的衍生檔案都是從這份縮小的檔案產生,而不是從你上傳的原圖:

尺寸從哪個檔案產生
full-scaled 副本
largemedium_largemediumthumbnail-scaled 副本
透過 add_image_size 註冊的自訂尺寸-scaled 副本
佈景主題和外掛的尺寸,例如 woocommerce_thumbnail-scaled 副本
srcset 候選檔案-scaled 副本

就是這一件事,讓非常多人栽了跟頭。

為什麼「我的圖明明很銳利卻看起來糊糊的」通常就是這個原因

同時有兩件事在發生,而其中只有一件顯而易見。

顯而易見的那件是解析度。你為滿版主視覺上傳了一張 4000px 的照片,WordPress 交給瀏覽器的是 2560px。在一般螢幕上填滿 1600px 的容器,沒人看得出來。但在 2 倍的高解析螢幕上,那個容器需要大約 3200 個實體像素,實際只拿到 2560,瀏覽器就把差額放大補上。邊緣發軟、細節糊成一團,圖片裡的文字也開始模糊。

比較不明顯的那件是重新編碼。-scaled 副本並不是你檔案的無損裁切版。WordPress 會把你上傳的圖片解碼、縮小,再用它自己的 JPEG 品質設定重新壓縮。如果你的原圖本來就是從 Lightroom 或手機出來的壓縮 JPEG,那就是第二代編碼:壓縮瑕疵疊在壓縮瑕疵上面。細微的細節、底片顆粒和平滑的漸層受害最深。就算像素尺寸看起來夠用,你還是看得出來。

在改任何東西之前先確認。把圖片在新分頁開啟,讀網址裡的檔名。出現 -scaled.jpg 就代表上限確實生效了。如果是像 -1536x1024.jpg 這種帶尺寸的後綴,那是另一回事 —— 是 srcset 挑到了一個太小的中間尺寸,這個門檻篩選器幫不了你。

在伺服器上:

find wp-content/uploads -name '*-scaled.*' | wc -l

如果這個數字很大,代表這個上限一直在形塑你的整個媒體庫。

你也可以把檔案丟進關閉 scaled 圖片工具,在決定設定值之前先看看某個來源檔會不會觸發這個門檻、縮小後的副本又會落在什麼尺寸。

誠實面對取捨

多數文章告訴你關掉這個上限會多耗磁碟空間。這是反過來的,值得說清楚。

單張圖片的磁碟用量其實會略微下降。 門檻開著時,WordPress 會同時保留你的原始檔一份較大的縮小副本。關掉之後,你只留下原始檔。一個檔案,而不是兩個。

流量和頁面重量會上升,有時候上升很多。 上限關掉之後,full 就是你原封不動的上傳檔。任何會連結或渲染完整尺寸的東西 —— 燈箱、相簿外掛、「檢視原圖」連結、主視覺會請求 full 的佈景主題 —— 現在送出的檔案可能是 6MB 而不是 900KB。在行動裝置上這是實實在在的 Largest Contentful Paint 問題,而且圖片 CDN 不見得救得了你,因為有些 CDN 超過某個大小上限就直接放行不處理。

上傳時的記憶體用量會上升。 在 PHP 裡處理一張 6000px 的圖片,比處理 2560px 的耗掉多得多的記憶體。在 PHP 記憶體上限偏低的廉價共享主機上,關掉這個上限很有可能讓你開始遇到上傳失敗,或縮圖只產生一半。把門檻調到 3840 而不是整個移除,是同一個改動比較安全的版本。

所以對大多數網站來說,合理的做法是把數字調高,而不是移除。真正該移除的情境,是你提供的圖片確實需要完整解析度:印刷品質的作品集、商品放大檢視、建築攝影,任何預期使用者會去細看原圖的場合。

正確地套用這個改動

1. 把篩選器放在能存活下來的地方。 子佈景主題的 functions.php 可以用。單一檔案的 mu-plugin 更好,因為換佈景主題不會悄悄把它失效掉。

<?php
/**
 * Plugin Name: Raise big image threshold
 */
add_filter( 'big_image_size_threshold', function () {
    return 3840;
} );

2. 把受影響的圖片重新上傳一次。 這是大家會跳過、然後斷定篩選器沒作用的那一步。門檻只在上傳的當下判斷一次,既有的附件會永遠沿用它們的舊中繼資料。請刪掉附件並重新上傳,然後修正文章裡的引用。

3. 不要指望重新產生縮圖能救回什麼。 透過 WP-CLI 執行 wp media regenerate,是從中繼資料所認定的完整檔案重建中間尺寸 —— 而對一張已經被限制過的圖片來說,那份檔案就是 -scaled 副本。它沒辦法還原已經被丟棄的細節。重新上傳之後拿它來收尾很有用,但單靠它當作解法則毫無用處。

4. 檢查結果,不要憑感覺假設。 重新上傳之後,在前台開啟圖片再讀一次檔名。沒有 -scaled 就代表篩選器生效了。

什麼時候不該關掉它

如果你的來源圖片本來就小於 2560px,卻還是看起來糊糊的,那這個門檻從頭到尾都沒參與。問題在於顯示框比可用的像素還大,答案是換一張更大的來源檔或縮小容器 —— 不是這個篩選器。

如果送出的檔名帶的是尺寸後綴而不是 -scaled,那是 srcset 挑了一個小的候選檔案。這通常是佈景主題宣告的內容寬度,和圖片實際渲染出來的框不一致。關掉這個上限對它一點影響都沒有。

還有,如果某個外掛正在把你的 src 改寫到最佳化服務或 CDN 代理,那在你確認那個代理實際送出什麼之前,上面這些都不適用。把 WordPress 應該產生的檔案,和瀏覽器實際載入的檔案對比一下;兩者對不上的時候,就去看夾在中間的那一層。

FAQ

常見問題

要怎麼關閉 WordPress 的 scaled 圖片?

在 big_image_size_threshold 上掛一個回傳 false 的篩選器,放進 functions.php 或一個小型的 mu-plugin 裡。回傳 false 會完全關閉這個上限,上傳的圖片會保留原始尺寸,也不會產生 -scaled 副本。如果改成回傳一個數字,例如 3840,那是把上限調高,而不是移除。

WordPress 檔名裡的 -scaled 後綴代表什麼?

它代表這是 WordPress 重新編碼過的副本,因為你上傳的圖片最長邊超過了 2560px。這份副本會成為整個網站上的完整尺寸。你的原始檔案仍然留在磁碟上、檔名照舊,但前台不會有任何地方連到它,而且每一個縮圖和 srcset 候選檔案都是從這份縮小過的副本產生的。

關掉 scaled 圖片會用掉更多磁碟空間嗎?

以單張圖片來說通常反而略少,因為 WordPress 不再在你的原始檔案旁邊多寫一個大檔案。真正的代價是流量,不是儲存空間。上限關掉之後,任何連到完整尺寸的地方都會送出你原封不動的上傳檔,在手機網路上那可能是好幾 MB。

關掉這個門檻能修好已經糊掉的圖片嗎?

不能。這個篩選器只影響之後新上傳的圖片。已經在媒體庫裡的圖片,中繼資料仍然指向它的縮小副本,重新產生縮圖也只是從那個已被限制過的檔案再建一次而已。想要救回解析度,只能在篩選器生效之後刪掉該附件並重新上傳。

2560px 這個門檻值得保留嗎?

對大多數內容型網站來說,值得。2560px 的來源檔足以應付 1280px 顯示框在 2 倍像素密度下的需求,而這正是最常見的情況。如果你有滿版主視覺、商品放大檢視或攝影作品集,就調高到 3840。只有在你真的需要送出未經處理的原始檔時,才整個關掉。