好長時間沒有關注 WebP 的支持性了,乍一看欸好像連 QQ 瀏覽器都能完美支持 WebP 了。很早之前就有關注 WebP-Server 這一過渡工具,恰好最近糖哥送了博主一台騰訊雲無憂輕量,在國內的輕量上部署一番,感受一下 WebP 帶來的提升。
一、概述#
WebP 是由 Google 開發的一種高效的圖片壓縮方案( Google WebP ),相比無損的 png 一般情況下 WebP 20% 有損壓縮能夠達到最高 75% 的壓縮比例。也正如 Google 宣傳的那樣,WebP 的壓縮率通常比 JPEG 和 JPEG 2000 平均高出 30%,而又不會降低圖片質量。
但是直至 2023 年,純 WebP 存儲依然面臨著很大的歷史遺留問題。訪問方面問題相對比較小,僅是 iOS 14 以前的 Safari 並不支持,國內外主流的現代瀏覽器都已經悉數支持了 WebP 圖片的加載(支持性統計)。但是各類生產力工具,比如 Ps 、Ai 等依然不支持加載 WebP 圖像,如果原始圖片僅保留 WebP 的話意味著放棄了一小部分舊設備加上失去了編輯的便利性。一邊是 WebP 帶來極致的媒體加載體驗,一邊是失去部分編輯的便利性,博主之前常常糾結於這些取捨,礙於不能完美解決問題而對新技術望而卻步。
前一段時間,偶然的機會我的群友提到了 WebP-Server 這個過渡工具。這是一個基於 go 語言的 WebP 轉換中間件,與很多 CDN 提供的過渡策略一樣,能夠在使用原圖儲存的基礎上,通過訪客 UA 判斷瀏覽器支持性決定返回 WebP 或原圖。相應的,WebP-Server 也能夠支持生成 WebP 緩存,以及像 CDN 一樣作為邊緣訪問節點實現對源站請求的壓縮。
-
項目首頁: https://webp.sh
縱觀我們國內的伺服器市場,在個人經濟能力能夠承受範圍的帶寬最大也就 4-5M 。基於這樣的假設,我們可以理論計算一下,5M 的帶寬大約能為你提供 640k/s 的傳出能力,以博主的經驗平均 8 張圖 / 頁面、100k / 圖,單個 PV 下就要佔滿帶寬 1.25 秒完成圖片的加載。但是在 20% 有損 WebP 壓縮的情況下,圖片平均大小降至 16-25k ,能夠使 1 秒內 PV 並發能力提高 5 倍,這在伺服器帶寬非常捉襟見肘的國內網絡環境下對站點的負載能力提升是立竿見影的。也是基於這個現狀,如果自用的圖床能夠配置 WebP ,很可能就不必再為 CDN 額外付費,僅通過高質量的 BGP 網絡完成服務的提供。
在疫情後降本增效的大環境下,也只有騰訊雲 4 月上雲精選依然在提供三年 408 2C/2G/4M 和 628 2C/4G/5M 的輕量應用伺服器了。最近糖哥送了我一台騰訊雲的無憂輕量,1C/2G/5M 的配置與活動款帶寬基本一致。題外話,最近騰訊雲開放了無憂的付費升配通道,持有無憂的小夥伴在有需要的情況下可以按需選擇升級到更高的配置。
二、WebP Server#
由於 WebP-Server 需要 libaom 組件,並且需要 libc6>2.34 ,博主建議使用 CentOS 8 / Debian 11 及以上的系統。儘管較早的系統可以通過編譯來對 libc6 版本進行升級,但這是一個十分危險的操作,很可能會導致系統關鍵組件出現問題。因此對於較早的系統,博主更加推薦直接使用 docker 進行部署(官方文檔),支持 ARMv7 ( 32bit )、ARM64 ( Aarch64 )和 AMD64 ( x86-64 ),可以在 DockerHub 上查看(點擊前往)。
# [/path/to/pics ] 指的是圖片路徑, [/opt/pics ] 指的是生成的 WebP 緩存路徑
docker run -d -p 3333:3333 -v /path/to/pics:/opt/pics --name webp-server webpsh/webp-server-go
手動安裝的話,必要的組件就是 libaom3 ,這個組件略微有點坑,預編譯包會默認讀取 libaom.so.3 這個.so ,安裝好之後如果還是提示找不到 libaom3 ,可以試試通過 ln -s 做一個軟連接。
# 安裝 libaom 庫
apt install libaom-dev
yum install libaom-devel
# 在 RHEL 系( CentOS )中解決找不到依賴的問題
ln -s /usr/lib64/libaom.so.0 /usr/lib64/libaom.so.3
#在 Debian 系中解決找不到依賴的問題
ln -s /usr/lib/x86_64-linux-gnu/libaom.so.0 /usr/lib64/libaom.so.3
預編譯包可以從 GitHub 下載(點擊前往),配置文件請按你的實際需要選擇模式並修改參數,以下各項參數的解釋已寫在註釋裡面,修改完成後可以保存為 config.json 文件。
#代理模式
{
"HOST": "127.0.0.1", //監聽本地主機,使用 0.0.0.0 可監聽全部
"PORT": "3333", //WebP Server 使用的本地端口
"QUALITY": "80", //壓縮質量,越低圖片壓縮比越高
"IMG_PATH": "https://test.webp.sh", //反代的站點
"EXHAUST_PATH": "/path/to/exhaus", //緩存 WebP 的保存路徑
"ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"], //壓縮的後綴類型
}
#本地模式
{
"HOST": "127.0.0.1", //監聽本地主機,使用 0.0.0.0 可監聽全部
"PORT": "3333", //WebP Server 使用的本地端口
"QUALITY": "80", //壓縮質量,越低圖片壓縮比越高
"IMG_PATH": "/path/to/pics", //本地圖片路徑,一般設置為站點根目錄
"EXHAUST_PATH": "/path/to/exhaust", //緩存 WebP 的保存路徑
"ALLOWED_TYPES": ["jpg","png","jpeg","bmp","gif"], //壓縮的後綴類型
"ENABLE_AVIF": false //av1 壓縮支持,暫不建議使用
}
直接安裝的話建議使用 systemd 啟動服務,以下是一個一鍵寫入 webp.service 的示例,修改好 webp-server 二進制文件和 config.json 文件的路徑,直接粘貼進 ssh 窗口即可。
cat > /etc/systemd/system/webp.service <<EOF
[Unit]
Description=WebP Server
Documentation=https://github.com/n0vad3v/webp_server_go
After=nginx.target
[Service]
Type=simple
StandardError=journal
AmbientCapabilities=CAP_NET_BIND_SERVICE
WorkingDirectory=/[程序目錄]/webp-server
ExecStart=/[程序目錄]/webp-server/webp-server-linux-amd64 --config /[程序目錄]/webp-server/config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=3s
[Install]
WantedBy=multi-user.target
EOF
至此,你就可以使用 service webp start|stop|status 來控制 WebP Server 的運行了,確認無誤後使用 systemctl enable webp 來允許其開機啟動。
三、NGINX 設置#
在 WebP-Server 工作正常之後,我們需要在 NGINX 上配置一個反向代理,將 jpg|jpeg|gif|png|bmp 這些後綴的媒體文件交給 WebP-Server 來處理。以下是一個示例,加在 NGINX 對應的 vhost 中即可。需要注意的是,開啟了 WebP 自動返回之後,同時需要在 vhost 中刪掉 NGINX 對相關媒體後綴的緩存內容,以免將 WebP 返回給了不支持的設備。
# 將 jpg|jpeg|gif|png|bmp 請求轉發至本地 3333 端口
location ~* \.(?:jpg|jpeg|gif|png|bmp)$ {
proxy_pass http://127.0.0.1:3333;
proxy_set_header X-Real-IP $remote_addr;
proxy_hide_header X-Powered-By;
proxy_set_header HOST $http_host;
add_header Cache-Control 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0';
}
四、補充 & 總結#
在撰寫文章的過程中,有朋友提醒說目前該程序存在內存洩漏的情況(點擊前往),作者建議使用 Docker 通過限制內存使用來避免這個問題。這個問題是在多人同時訪問單個媒體資源時 WebP Server 會對同個文件啟動多個壓縮進程,進而導致異常的內存佔用。如果直接安裝同時為了更好的體驗,緩存預熱是一個非常明智的選擇。
# 啟用 4 進程對配置目錄進行緩存預熱
./webp-server -prefetch -jobs=4 --config /[程序目錄]/webp-server/config.json
作者在 GitHub 上的預編譯包僅提供了 64 位 x86 的架構,博主感覺作者是在 RHEL8 系上構建的預編譯包,如果想在其他平台使用可以考慮使用 docker 或者按照文檔(點擊前往)進行編譯,整個流程並不複雜。配置好後打開 F12 Network 選項卡,勾選類型選項或者在圖片的 content-type 可以看到,我們實際訪問的圖片已經被壓縮成了 webp 。最後也再次感謝作者寫出這樣一個好用的小工具吧~
原文鏈接: https://luotianyi.vc/6907.html
若有任何問題,歡迎大家批評指正~