根本原因是浏览器未算出所需物理像素数:sizes缺失或错误导致按1x DPR计算,即使设备为2x也只加载400w图,渲染时被拉伸模糊;且<source>的sizes无效、混用w/x、或<source>中写2x均会触发回退。

picture 标签本身不读取分辨率,浏览器靠 srcset 的 2x 描述符 + sizes 属性,结合设备 window.devicePixelRatio 自动选图;漏写 sizes、把 sizes 写在 <source> 里、或混用 w 和 x,都会导致只加载 <img src> 回退图。
为什么写了 2x 却还是加载了模糊小图
根本原因不是浏览器没识别 DPR,而是它没算出“该要多大物理像素”。sizes 缺失或写错时,浏览器默认按 1x DPR 计算所需宽度,哪怕设备是 2x 也只去拿 400w 图——结果渲染时被拉伸模糊。
常见错误包括:
• <img> 上没写 sizes(<source> 上写的 sizes 完全无效)
• sizes="(max-width: 600px) 100vw, 50vw" 中的括号漏了或单位少了 px
• CSS 实际设了 width: 300px,但 sizes 写成 "100vw",预估偏差直接选错源
• 同一个 srcset 里混了 photo.jpg 1x 和 photo-800w.jpg 800w,整个值被解析为无效
<source> 的 media 和 <img> 的 srcset 怎么分工
<source> 只管“按视口宽度选哪一组图”,<img> 的 srcset 才管“在这组里按 DPR 选哪张”。
例如:
• <source media="(max-width: 480px)" srcset="icon-sm.png"> → 这行只告诉浏览器:小屏时启用这组资源
• <img src="icon-sm-1x.png" srcset="icon-sm-1x.png 1x, icon-sm-2x.png 2x"> → 真正让 DPR=2 设备加载 icon-sm-2x.png 的是这一行
关键点:
• <source> 的 srcset 里写 2x 没用,浏览器完全忽略
• <img> 的 src 必须存在,否则不支持 <picture> 的老浏览器会空白
• 多个 <source> 必须顺序合理:宽屏断点放前,窄屏兜底放后,否则高分辨率小屏设备永远卡在第一个 max-width 条件里
验证是否真加载了高分图,别只看 Network 面板
Network 面板显示的文件名可能被缓存、CDN 或 Service Worker 干扰,实际渲染的未必是它。
可靠验证方式:
• 刷新页面后,在 Elements 面板选中 <img>,展开 Properties → 查看 currentSrc 值是不是带 @2x 或宽尺寸路径
• DevTools → Rendering → 勾选 “Device emulation”,手动设 DPR 为 2 或 3,再观察 currentSrc 是否切换
• 控制台执行 console.log(window.devicePixelRatio),确认当前 DPR,并核对是否匹配你写的 media 或 srcset 条件
• 禁用缓存硬刷(Cmd+Shift+R),避免看到 304 响应误判为成功加载
立即学习“前端免费学习笔记(深入)”;
现代格式(WebP/AVIF)和 DPR 适配能一起用吗
能,但必须分层:先用 <source type> 过滤格式支持,再在匹配的 <source> 内部靠 <img> 的 srcset 处理 DPR。
正确结构:<source media="(min-width: 768px)" type="image/avif" srcset="hero-avif-1x.jpg, hero-avif-2x.jpg"><source media="(min-width: 768px)" type="image/webp" srcset="hero-webp-1x.jpg, hero-webp-2x.jpg"><img src="hero-jpg-1x.jpg" srcset="hero-jpg-1x.jpg 1x, hero-jpg-2x.jpg 2x" alt="...">
注意:
• type 必须放在 <source>,且顺序重要:AVIF 放 WebP 前,因为浏览器找到首个支持的就停
• 每个 <source> 的 srcset 本身不参与 DPR 匹配,真正起作用的仍是末尾 <img> 的 srcset
• 服务端返回的 Content-Type 必须和 type 一致,否则 Chrome 会标记为 blocked:mime-type,整条 <source> 失效



















