一张 1600px 的大图直接塞给手机,等于让用户在 4G 上下载 5 倍于需要的流量。picture + srcset + sizes 让浏览器自己挑最合适的那一档——这是移动端图片优化里投入产出比最高的一步。
-
宽度档位
-
格式数量
-
source 标签数
-
srcset 条目数
每个 <source> 对应一种格式,srcset 里为每个宽度档写一条「文件名 宽度w」;浏览器按 sizes 描述的实际显示宽度乘以设备像素比,从 srcset 中挑选最合适的一条下载。最后的 <img> 是不可省略的兜底与无障碍入口。
浏览器是怎么挑图的
srcset 不是让开发者指定用哪张图,而是提供一份候选清单,由浏览器结合两件事自己决定:当前视口宽度(由 sizes 描述)和设备的像素比(DPR)。
举个实际过程:视口 375px 的 iPhone(DPR = 3),若 sizes 描述为 100vw,浏览器判断需要 375 × 3 = 1125 物理像素宽的图,于是从 400/800/1200/1600 里选 1200w 那一档。同一个页面在 1440px 的笔记本(DPR = 2)上,若显示宽度是 720px,需求是 1440 物理像素,就会选 1600w。
sizes 写错,一切都白搭
这是最常见的失效原因:sizes 写得不真实,浏览器就会挑错档位。默认值是 100vw(占满视口宽),但如果图片实际只占半屏,浏览器会多下载一倍的图。
sizes="(max-width: 600px) 100vw, (max-width: 1200px) 50vw, 33vw"
上面这行的意思是:窄屏全宽、中屏半宽、宽屏三分之一宽。写法要从窄到宽依次排列,最后的无媒体条件项作为兜底。
为什么要放 AVIF 在最前面
浏览器会使用第一个它支持的 <source>,所以顺序就是偏好顺序:越新的格式写越前。同画质下 AVIF 通常比 WebP 再小 20%–30%,WebP 又比 JPEG 小 25%–35%。把三者都列上,老浏览器自然回落到 JPEG,不会有兼容性问题。
四个容易踩的坑
- 漏掉
<img>:picture 里的 img 不是可选项。少了它,不支持 picture 的环境什么也看不到,alt 文本也无处可放。 - 首屏大图用懒加载:LCP 图片设
loading="lazy"会拖慢最大内容绘制时间。首屏图应设为 eager,并加上fetchpriority="high"。 - 宽度档位过多:4–5 档通常足够。档位太密会让构建产物数量爆炸,收益却极其有限。
- 忘记写
width/height:没有尺寸声明会导致布局偏移(CLS)。现代做法是用 CSS 的aspect-ratio或在 img 上写宽高属性。
你可能还想问
响应式图片有什么好处?
让浏览器按屏幕尺寸与像素密度选择合适资源,避免小屏加载大图浪费带宽,同时提升加载速度与视觉质量。
新旧格式怎么兼顾?
用多源声明依次列出新格式与兼容格式,浏览器选第一个支持的;这样新浏览器更省流量,旧浏览器也有兜底。
尺寸属性要写吗?
要。声明宽高能让浏览器提前预留位置,减少内容跳动导致的布局偏移,对体验与性能指标都有正向作用。
速查在线工具箱