学完这篇,你能根据图片内容快速判断该用 WebP、AVIF 还是 SVG,并写出带回退的 <picture> 代码,让老浏览器也不白屏。
第一步:先按「图像类型」分流,这一步决定 90%
打开你的图片目录,把文件分成两堆:
- 照片、截图、带渐变的复杂图 → 位图,在 WebP / AVIF / JPEG 之间选
- 图标、Logo、流程图、折线图、单色 UI 元素 → 矢量,用 SVG
判断标准很简单:这张图放大后会不会糊?会糊就是位图,不会糊且边缘锐利就是矢量素材。把 Logo 硬做成 PNG 再压成 WebP,是新手最常犯的浪费。
注意:SVG 不适合放照片。把 JPG 塞进 <svg> 里包一层,体积只会更大,渲染还慢。
第二步:位图优先 AVIF,回退 WebP,兜底 JPEG
现代浏览器已经能通过 <picture> 自动挑格式,浏览器不认识的 type 会直接跳过,不会报错:
<picture>
<source type="image/avif" srcset="/img/cover-800.avif 800w, /img/cover-1600.avif 1600w" sizes="(max-width: 768px) 100vw, 800px">
<source type="image/webp" srcset="/img/cover-800.webp 800w, /img/cover-1600.webp 1600w" sizes="(max-width: 768px) 100vw, 800px">
<img src="/img/cover-800.jpg" alt="封面图" width="800" height="450" loading="lazy" decoding="async">
</picture>
顺序不能反:AVIF 写最前,WebP 居中,<img src> 放最后兜底。<source> 是从上往下匹配的,顺序错了就永远命中第一个能用的。
体积上,同等画质下 AVIF 通常比 WebP 再小 20%~50%,WebP 比 JPEG 小 25%~35%。所以 AVIF 值得当首选,但它的编码速度明显更慢,批量转图时别在请求线程里实时转。
第三步:用命令行批量生成三种格式
装好 cwebp、avifenc(或直接用 squoosh 网页版):
cwebp -q 80 cover.jpg -o cover.webp
# AVIF,质量 50 大致相当于 JPEG 80 的观感
avifenc -q 50 cover.jpg cover.avif
注意:AVIF 的 -q 刻度比 JPEG/WebP 敏感,从 50 开始试,肉眼对比后再上下调 5,不要照抄 JPEG 的 80。
第四步:SVG 用它该用的方式引入
图标类 SVG 有两种引入法,按是否需要换色决定:
需要跟随文字颜色变化 → 内联
<svg viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M4 12h16M12 4v16"/>
</svg>
currentColor 会让图标自动继承父元素 color,深色模式、hover 换色全部免费。
只是装饰性插图 → 用 <img>
<img src="/img/empty-state.svg" alt="暂无数据" width="160" height="120">
注意:用 <img> 引入的 SVG 处于独立文档,外部 CSS 进不去,currentColor 也不生效。另外若站点允许用户上传 SVG,务必做白名单校验与内容消毒,SVG 能内嵌 <script>,直接当 HTML 打开会有 XSS 风险。
第五步:别忘了 width/height 和 loading
格式选对了,尺寸写错了照样掉分。
- 每张图都写
width / height(或 CSS aspect-ratio),否则图片加载时页面会跳一下,影响 CLS 指标
- 首屏大图不要加
loading="lazy",会拖慢 LCP;正文中下方的图片才加
- 配合
srcset + sizes 给不同屏幕发不同尺寸,手机别硬扛 1600px 大图
第六步:上线前用 DevTools 验证
Chrome DevTools → Network → Img 筛选,看两件事:
- 实际下载的
Type 是不是 avif / webp(如果不是,说明 <source> 顺序或 type 写错了)
Size 有没有超预期,单张内容图控制在 200KB 以内比较稳
再把浏览器切到移动端模拟、禁用缓存刷新一次,确认回退链路真的能走到 JPEG。
注意:本地开发环境如果用了图片处理中间层(CDN、压缩插件),可能悄悄把 AVIF 又转回 JPEG,以真实响应头 Content-Type 为准。
小结
- 先分类:照片走位图,图标图形走 SVG,不要互相将就
- 位图三段式:AVIF → WebP → JPEG,
<source> 顺序从上到下必须由新到旧
- SVG 要换色就内联配
currentColor,纯展示用 <img>,用户上传必须消毒
width / height 必写,首屏图别加 loading="lazy"
- 收尾靠 DevTools 验证实际命中的格式与体积,别只信代码看起来对