GIF 轉 Animated WebP:省最多的一刀
25 張正式環境的 GIF 轉成 animated WebP 後,中位數檔案大小少了 51%。全部 25 張保留了影格數和時間。這篇記錄數據、動畫完整性檢查,以及一個 libvips 的坑。
我們問了什麼
三種來源格式(JPEG、GIF、PNG)裡,哪一種浪費最多頻寬?GIF。一張 GIF 今天大概花了需要量兩倍的位元組。我們把 25 張正式環境 GIF 轉成 animated WebP 和 animated AVIF。然後逐張比較大小和品質。
怎麼測量的
每張 GIF 經過跟圖片轉換服務相同的管線。Go 圖片函式庫(govips v2.15.0)處理 WebP 路徑。AVIF 路徑需要另一個工具(下面坑的段落會講)。每次轉換都記錄檔案大小、SSIM(結構相似度,0 到 1)和編碼時間。
p25 / p50 / p75 是四分位數。四分之一的圖至少省到 p25 的值。一半的圖至少省到 p50 的值。
大小縮減
| 轉換 | p25 | p50 | p75 | SSIM p50 | SSIM 最低 |
|---|---|---|---|---|---|
| GIF 轉 WebP (q80) | 41.1% | 51.0% | 61.6% | 0.980 | 0.949 |
| GIF 轉 AVIF (q80) | 46.6% | 54.0% | 63.3% | 0.994 | 0.979 |
兩種格式在中位數都把 GIF 砍了一半。AVIF 多壓 3 個百分點,但跟共同對原始 GIF 的改善相比,差距很小。
按原始檔案大小分組
節省幅度在所有大小分組都成立,不只是某一段:
| 大小分組 | 數量 | 原始大小範圍 | WebP 節省 p50 | AVIF 節省 p50 |
|---|---|---|---|---|
| 小 | 7 | 19.5 KB 到 36.9 KB | 40.6% | 49.4% |
| 中 | 11 | 53.2 KB 到 164.1 KB | 61.6% | 63.3% |
| 大 | 7 | 183.6 KB 到 290.9 KB | 45.6% | 50.7% |
中等大小的 GIF 省最多。小 GIF 百分比省較少,但本來就已經輕了。
動畫完整性
把 GIF 轉成另一種格式可能破壞動畫。影格可能合併,時間可能偏移,循環可能停止。我們檢查了全部 25 個轉換結果:
- 影格數: 25 張全部通過。轉換後的檔案保留了跟來源 GIF 相同的影格數。
- 影格延遲: 通過。動畫時間與原始一致。
- 視覺品質: 所有 SSIM 值都在 0.949 以上。肉眼看不出差別。
Animated AVIF 的坑
這段講的是我們在基準測試過程中發現並修復的一個 bug。它重要,因為它說明了為什麼 animated WebP 今天比較安全。
第一次嘗試:govips ExportAvif。 Go 圖片函式庫寫出了一個多頁 HEIF 容器(檔案回報有多頁)。但它沒有把 GIF 的每格延遲時間轉進 HEIF 序列。瀏覽器只顯示第一格,動畫看起來是靜態的。
根本原因: libvips 的 ExportAvif(heifsave 操作)把每格寫成一個 HEIF 頁面,但不寫每格延遲的中繼資料。這是 libvips 的限制,不是 AVIF 格式的限制。
第二次嘗試:ffmpeg,沒加 -fps_mode passthrough。 我們換用 ffmpeg。它產生了 1,000 個內插影格,跑在 100 fps,而不是原始的 4 格。檔案比來源 GIF 大 2 倍。第一格停了 2 秒,之後動畫跑太快。看起來壞掉了。
第三次嘗試:ffmpeg 加上 -fps_mode passthrough。 這個旗標告訴 ffmpeg 保留原始影格數和每格時間。成功了。全部 25 張 GIF 轉出來的影格數正確、延遲正確、SSIM 正確。
結論: animated WebP 在 govips(libvips 的 Go 封裝)裡原生就能用。Animated AVIF 需要另外一條 ffmpeg 路徑加上特定旗標。對正式環境的圖片轉換服務來說,多一條路徑就是多一份複雜度和風險。這是先出 WebP 的又一個理由。
編碼時間
編碼時間(轉換一張圖的 CPU 成本)是上傳時的一次性成本。使用者不會等到這個。但它影響轉換服務處理一批圖片的速度。
| 轉換 | p25 | p50 | p75 |
|---|---|---|---|
| GIF 轉 WebP | 8 ms | 45 ms | 61 ms |
| GIF 轉 AVIF (ffmpeg) | 366 ms | 1,793 ms | 2,333 ms |
| JPEG 轉 WebP | 5 ms | 14 ms | 23 ms |
| JPEG 轉 AVIF | 171 ms | 340 ms | 521 ms |
| PNG 轉 WebP | 7 ms | 9 ms | 17 ms |
| PNG 轉 AVIF | 205 ms | 268 ms | 577 ms |
GIF 轉 WebP 中位數花 45 ms。GIF 轉 AVIF 花 1,793 ms,慢 40 倍。
GIF 轉 AVIF 編碼時間高,因為它走 ffmpeg 路徑(上面那個坑的修法)。JPEG 和 PNG 的差距較小(24 到 30 倍)。那兩種對 WebP 和 AVIF 都用 govips 路徑。
編碼速度的差異不是拒絕 AVIF 的理由。但它代表轉換服務需要更多容量來處理 AVIF。第一波上線,WebP 是比較輕的選擇。
對投放體驗的意義
GIF 是格式切換對使用者體驗影響最大的地方。同一段動畫,少 51% 的資料,所有影格和時間都保留。轉換路徑(govips)原生支援 animated WebP,不用特殊工具,不用旗標,不用試第二次。
WebP 和 AVIF 在全部三種來源格式的完整比較,見 Part 02:WebP vs AVIF。
參考來源:
- https://github.com/nicolo-ribaudo/tc39-proposal-is-usable-by-default(libvips animated AVIF 限制,以 govips v2.15.0 + libvips 8.18.6 驗證)
- https://ffmpeg.org/ffmpeg.html#Options(ffmpeg
-fps_mode passthrough旗標)
延伸閱讀: 回到圖片格式基準測試總覽。GIF 動畫在 libvips 裡如何以 page-strip 運作,見圖片處理系列的 libvips 把動畫存成 page-strip。