浏览器先根据sizes计算图片渲染宽度,再从srcset中选取最接近且不小于该宽度的候选图;sizes必须真实反映css布局宽度,缺之则退化为dpr匹配或加载src,w描述符需对应图片固有像素宽。

浏览器怎么决定加载哪张图
浏览器不是靠猜,而是按明确规则从 srcset 中选图:先算出图片在当前页面的「渲染宽度」,再挑一张 srcset 里最接近且不小于该宽度的图。这个「渲染宽度」由 sizes 属性给出,不是 CSS 宽度,也不是视口宽度,而是「这张图在布局中实际占多少空间」。
常见错误是把 sizes 写成固定值,比如 sizes="50vw",结果在窄屏下图片只占 30vw 却仍加载 50vw 的图;或者漏写 sizes,浏览器只能退回到设备像素比(DPR)逻辑,导致小屏加载大图。
-
sizes必须与 CSS 布局一致——如果图片容器用max-width: 600px+width: 100%,sizes就得写成(min-width: 600px) 600px, 100vw - 所有
srcset中的w描述符必须是图片的真实固有宽度(单位 px),不能是缩放后尺寸 - 不支持
srcset的旧浏览器会直接加载src,所以src必须是可用的最小兼容图
<picture></picture> 的匹配顺序和 fallback 机制
<picture></picture> 不是并行判断所有 <source></source>,而是**从上到下逐个检查 media 条件**,命中第一个就停止,加载对应 srcset;全都不匹配时,才用底部 <img> 的 src。
容易踩的坑是 media 条件重叠或顺序错乱。比如先写 max-width: 768px,再写 max-width: 480px,后者永远没机会触发;又或者漏掉 <img>,整个 <picture></picture> 在不支持的浏览器里直接不显示。
-
media必须是合法媒体查询,不能写480px或small -
type属性用于格式探测(如type="image/webp"),浏览器不支持该 MIME 类型时跳过该<source></source> -
<img>的alt是必需的,它不属于<source></source>,也不继承自上面的<source></source>
为什么 max-width: 100% 不等于响应式图片
CSS 的 max-width: 100% 只控制显示尺寸,不改变资源加载行为。一张 4000×2000 的 JPEG 即使被 CSS 缩到 300px 宽,依然会完整下载 4MB 数据——流量、解码、内存全浪费。
真正的响应式图片必须让浏览器在发起 HTTP 请求前就知道「该拉哪张」,这只能靠 HTML 层的 srcset 或 <picture></picture> 驱动。CSS 是事后修饰,HTML 才是资源调度源头。
- 仅用 CSS 缩放 + 大图 = 移动端卡顿、3G 下加载失败、Lighthouse 图片评分低
-
loading="lazy"和decoding="async"是辅助项,不能替代srcset的资源选择逻辑 - 现代格式(WebP/AVIF)必须配合
<picture></picture>的type回退,否则 Safari 16 以下、Firefox 旧版等会空白
高 DPR 设备(Retina)的加载逻辑差异
当设备像素比(DPR)为 2x 时,浏览器会把「渲染宽度 × DPR」作为目标尺寸去匹配 srcset。比如 sizes="50vw" 在 375px 宽手机上算出渲染宽度是 187.5px,乘以 DPR=2 后变成 375px,于是可能选中 480w 而非 320w 的图。
这意味着你不能只按视口宽度准备图片,还得考虑 DPR 分布。简单策略是:提供 1x、2x、3x 版本时用 x 描述符;按宽度适配时统一用 w 描述符,但图片集要覆盖 1x–3x DPR 下的常见渲染宽度区间。
- 混用
w和x在同一srcset中会导致浏览器忽略整条属性 - DPR 判断发生在客户端,服务端无法通过 User-Agent 准确预判,所以必须靠前端声明
- Chrome DevTools 的 Network 面板里看「Size」列,能验证是否真加载了预期尺寸的图
sizes 写错、<source></source> 顺序乱、漏兜底 <img>,都会让这套机制彻底失效,退化成传统大图加载。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











