srcset + sizes 是体积优化的前提,必须配对使用;sizes 告诉浏览器图片显示宽度,避免手机加载超大图;WebP/AVIF 需 type 回退兜底;懒加载与异步解码缺一不可;服务端预生成多尺寸多格式文件是基础。

srcset + sizes 是体积优化的前提,不是可选项
不配 sizes,srcset 就等于白写。浏览器默认按 100vw 估算图片显示宽度,手机可能加载 3840w 的图——体积翻 5 倍,带宽全浪费。你看到的“响应式”只是 CSS 缩放,原始文件照常下载。
必须明确告诉浏览器:“这张图在不同视口下实际占多宽”。比如 banner 图在小屏占满,在桌面只占 1/3:
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"-
srcset中每个图必须带w描述符(如768w),不能混用x和w,否则整条属性被忽略 - 服务端必须已生成对应尺寸的文件——前端无法实时缩放或降采样
WebP/AVIF 不是“开了就快”,必须用 回退
直接把 src 换成 .webp,Safari 13 以下、IE、部分安卓 WebView 会显示空白。现代格式节省 30–50% 体积的前提,是安全兜底。
正确结构只有一种写法:
立即学习“前端免费学习笔记(深入)”;
<picture> <source srcset="hero-768w.webp 1x, hero-768w@2x.webp 2x" type="image/webp"> <source srcset="hero-768w.jpg 1x, hero-768w@2x.jpg 2x" type="image/jpeg"> <img src="hero-768w.jpg" alt="主图"> </picture>
- 每个
<source>必须带type,浏览器靠它跳过不支持的格式 - 不要只写一个
<source>+<img>:没有type的<source>会被忽略,<img>成为唯一 fallback - AVIF 同理,但需确认 CDN 支持(Cloudflare、AWS CloudFront 已全量支持)
懒加载和异步解码不是锦上添花,而是防崩溃刚需
一张 8MB 的 TIFF 或未压缩 PNG,哪怕只设了 width="300",浏览器仍要完整下载、解码、渲染——低端安卓机内存直接爆掉,页面白屏。
- 加
loading="lazy":首屏外图片延迟触发请求,避免阻塞 HTML 解析和关键资源加载 - 加
decoding="async":解码任务脱离主线程,尤其对大 JPEG 有效,UI 不卡顿 - 两者缺一不可:只 lazy 不 async,图片进入视口时仍会卡顿;只 async 不 lazy,初始请求数爆炸
服务端预处理这一步,前端真做不了
所有“体积优化”都建立在服务端已有多个尺寸+格式的文件基础上。前端不可能在用户设备上实时 resize、转 WebP、删元数据。
必须做的三件事:
- 用
convert(ImageMagick)或squoosh-cli批量生成:convert input.tiff -resize 768x -quality 82 -interlace Plane output-768w.jpg - 务必加
-interlace Plane输出渐进式 JPEG,首帧模糊快显,用户体验更稳 - 禁止上线
.tiff、.psd、未压缩.png:它们无流式解码支持,浏览器必须等全部字节到达才开始处理
最容易被跳过的,就是生成多档位文件这一步——后面所有 HTML/CSS 都依赖它存在。没这步,srcset 只是空架子,picture 只是装饰。



















