WebP 与 AVIF:按能力协商,而不是一刀切

AVIF 体积更小但编码慢、老设备不支持。正确做法是按客户端的 Accept 头协商,而不是全站换成一种格式。

6 分钟协议与压缩
WebP 与 AVIF:按能力协商,而不是一刀切

要点

按 Accept 头协商图片格式,并 Vary: Accept。注意这会让缓存副本翻倍——只 Vary 必要的那一个头。

本文目录
  1. 01三种格式的取舍
  2. 02怎么协商
  3. 03实践建议

三种格式的取舍

格式相对体积编码速度兼容性
JPEG基准全支持
WebP明显小于 JPEG较快现代浏览器普遍支持
AVIF进一步小于 WebP较新浏览器支持
具体压缩率随图片内容差异很大,此处只示意相对关系。

AVIF 的编码耗时明显高于 WebP,这在实时转码场景下是实际成本。对图片量大的站点,通常做法是异步预生成而不是请求时转码。

怎么协商

# 浏览器声明能力
Accept: image/avif,image/webp,image/*,*/*;q=0.8

# 服务端按能力返回,并声明缓存按此头分裂
Content-Type: image/avif
Vary: Accept

Vary: Accept 的代价要算清

Vary: Accept 会让同一个 URL 按 Accept 头的取值分裂出多份副本。Accept 头的实际取值种类比想象中多(不同浏览器版本略有差异),可能导致副本数超出预期。用 CDN 的「图片格式」缓存键(多数厂商提供,把 Accept 归一化成几档)比直接 Vary 整个 Accept 更可控。

实践建议

  • 前端用 <picture> 加多个 <source> 让浏览器自己挑,这样每种格式各有独立 URL,完全不需要 Vary;
  • 走 CDN 图片处理时,优先用厂商提供的格式归一化缓存键;
  • 大图优先转 AVIF(收益大),小图用 WebP 就够(AVIF 的编码成本不划算);
  • 始终保留 JPEG 兜底,不要假设所有客户端都支持新格式。

在你的网站验证

边缘核验看你的图片对不同 Accept 头返回了什么格式