本篇文章更新時間:2022/09/22
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
先前在粉絲頁上筆記過同事提出來 WordPress 網站想讓它支援 WebP 的資料。
WordPress v5.8
版後核心已經加入支援 WebP 格式,並原本預計要在 v6.1
變成預設轉換圖片的功能。
不過最近風向大變,不少人反彈讓這件事情變成「預設」,覺得應該要先用額外的外掛處理的形式來進行。
不得不說,看下方的各個縮圖與 WebP 格式壓縮對比列表圖,實在是滿驚人!原始檔案從 603K -> 45K
等於是多存一些小檔案,用空間來換速度效能的方式。
至於值不值得,我相信還是預算先決
。
論方便與維護成本(不考慮預算的話),第一名我會覺得每個月付 20 USD(Pro方案),讓 Cloudflare 幫你直接快取圖片並提供 WebP 格式輸出的做法,網站這邊啥都不用動,原地搞定,爽快!
其次的做法都是要有些技術底了:
- 網站上傳時就轉換 WebP 一份放主機,改網站伺服器的 rewrite 來提供 WebP 圖片。
- 網站介接 CDN/雲端轉換圖片 等服務,不論是網站這邊也存一份,還是 CDN 服務替換過的路徑來提供 WebP 服務都一樣,不需要網站主機伺服器的調整。
大致上就是上述兩類,而架設 CDN 的成本,扣除軟體還要修改,使用現成的開源圖片 CDN 服務,或是先前筆記過的 [WordPress] 客製化自己的內容傳遞網路(CDN)服務筆記,實際成本大概就是抓每個月一台 20 USD 主機,但那管理與維護的麻煩程度,我還是會覺得乾脆花一樣的錢,用 Cloudflare Pro。 哈哈
如果是套用其他 CDN 服務,用量計價方式的話,那可能前期低於 20 USD,但後期累積來的成本是動態且成長的形式,通常不會是一個好選項。(畢竟還有之後從這樣服務分手的代價要考慮)
如果本來就有使用 Cloudflare 的話,那他的 Image 這個產品可以參考。每個月 5USD 起,搭配 Offload, Store, Resize & Optimize with Cloudflare Images 這款外掛使用。
如果打算自建的話,比較建議搭配雲端架構的組合技: AWS S3 當上傳圖庫 -> 觸發 Lambda Serverless 無伺服器運算,處理圖片轉換 WebP 並存回 S3 -> Cloudfront 當 S3 加速器提供 CDN 服務
。
不用網站主機來算圖,減少對運算力的需求,也算是技術能力值要點高一點的終極做法了。
上述討論的「2」都偏向是整合其他服務類型的處理方式。原生就在 WordPress 網站全部完成「1」的作法,目前看下來就只有一套外掛深得我心: Warp iMagick - WordPress Image Compressor & Convert to WebP
雖然不在 WordPress.org 的外掛庫,但卻是最扎實沒有要你去串其他人服務或是授權的「本機轉換」外掛。
使用下來的缺點就是:上傳圖片因為要多轉一份 WebP 格式,所以....慢....,網站開越多版本的縮圖,就要 x2 的時間來算圖。
而優點就是可以針對 JPG/PNG/WebP 的縮圖相關品質等參數做更細部的調整。
這款外掛會需要伺服器有安裝上 GD 與 Imagick 的 PHP 延伸函式庫(extension),不過這也算 WordPress 安裝時建議的伺服器組態了。
另外就是 Nginx 伺服器支援的部分,作者有在這回答,按照說明補上這份 Recipe: serve WebP with nginx conditionally 的設定就好。
主要是 http
的 block 裡補上
map $http_accept $webp_suffix {
default "";
"~*webp" ".webp";
}
判斷有無接受 webp
請求格式的 HTTP 標頭,然後在 server
的 block 裡補下方這個判斷
location ~ .*\.(gif|jpg|jpeg|png|bmp)$ {
add_header Vary Accept;
try_files $uri$webp_suffix $uri =404;
expires 30d;
}
針對 image.png
判斷當前有沒有 image.png.webp
這檔案,有就用這提供。
至於回到最前面說的,目前官方會取向先用外掛形式來處理這個 WebP
。所以官方自己也有出一款外掛 Performance Lab,安裝開啟設定後,這款外掛是使用 modules/images/webp-uploads/fallback.js
JS 方式,取代頁面中圖片請求路徑,來達到請求 WebP
圖片目的,不用設定伺服器組態。
但官方這套,除了命名格式特殊外(image.png -> image-png.webp
),我還碰到刪除時會刪不到原始圖片的問題,需要補下方的 code 刪除。
function mxp_hotfix_webp_uploads_remove_sources_files($attachment_id, $att_post_obj) {
$metadata = wp_get_attachment_metadata($attachment_id);
// error_log('$metadata:' . json_encode($metadata) . PHP_EOL);
$upload_path = wp_get_upload_dir();
if (empty($upload_path['basedir'])) {
return;
}
$file = $metadata['file'];
$intermediate_dir = path_join($upload_path['basedir'], dirname($file));
$basename = wp_basename($file);
if (!isset($metadata['sources']) || !is_array($metadata['sources'])) {
return;
}
// $original_mime_from_post = get_post_mime_type( $attachment_id );
// $original_mime_from_file = wp_check_filetype( $file )['type'];
// Delete full sizes mime types.
foreach ($metadata['sources'] as $mime => $properties) {
if (!is_array($properties) || empty($properties['file'])) {
continue;
}
$full_size = str_replace($basename, $properties['file'], $file);
if (empty($full_size)) {
continue;
}
$full_size_file = path_join($upload_path['basedir'], $full_size);
if (file_exists($full_size_file)) {
// error_log('file_exists:' . $full_size_file . PHP_EOL);
// wp_delete_file($full_size_file);
$res = unlink($full_size_file);
if ($res === false) {
error_log('unlink faild:' . $full_size_file . PHP_EOL);
}
}
}
}
add_action('delete_attachment', 'mxp_hotfix_webp_uploads_remove_sources_files', 11, 2);
以上,就是目前針對 WordPress 網站想要相容 WebP 圖片格式的思路筆記。沒有一定規模的網站用付費方法雖然方便,但肯定是拉高營運成本,所以規模化之前使用站內外掛一次處理完,然後等流量起來後再轉上述的 CDN 處理方式都還來得及。
至於你如果本來就打算直接不管瀏覽器支援度(截至發文日,支援度為 97.17%)想直接自己只傳 WebP
格式圖片的話也不是不行,想辦法把 webp-hero - browser polyfill for the webp image format 這個套件補上你的主題,就可以了,也是一種 hack 的方式。但我個人覺得要把慣用的圖片格式都預先轉換成 WebP,應該沒多少人能辦到了XD