始终加载同一张图是因匹配逻辑未满足:浏览器按顺序逐个检查,首个media成立且type可用即停止;media语法错误、srcset缺失描述符、缺src、mime类型不匹配等均导致静默失败。

为什么写了 <picture></picture> 却始终加载同一张图
这不是浏览器“不工作”,而是匹配逻辑没被满足。浏览器按 <source></source> 顺序逐个检查,只要第一个 media 成立且 type 可用,就立刻选中并停止——后面的全被跳过。
-
media写错:比如media="max-width: 768px"缺括号,应为media="(max-width: 768px)";写成media="768px"直接被忽略 -
<source></source>没配srcset:空srcset或只写路径没加描述符(如"icon.png"而非"icon@2x.png 2x"),该<source></source>不参与 DPR 选择 -
<img>缺src:整个<picture></picture>渲染为空白,不是报错,是静默失败 - 服务器返回的
Content-Type和type="image/webp"不一致(比如返回text/plain),Network 面板会显示blocked:mime-type
<source></source> 里的 2x 描述符根本不起作用
这是规范行为,不是 bug。只要 <source></source> 带了 media 或 type,它的 srcset 就只取第一个资源,DPR 匹配逻辑完全不介入。
- 错误写法:
<source media="(max-width: 480px)" srcset="btn@2x.png 2x"></source>→ 小屏设备永远加载btn@2x.png,哪怕devicePixelRatio === 1 - 正确做法:把所有 DPI 版本都挪到最外层
<img>的srcset里,例如srcset="btn@1x.png 1x, btn@2x.png 2x, btn@3x.png 3x" -
<source></source>只负责断点(media)或格式降级(type),别指望它做 DPR 切换
<img> 上加了 sizes 导致 2x 失效
一旦 <img> 声明了 sizes(哪怕只是 sizes="100vw"),浏览器立刻切换到「宽度匹配模式」,彻底忽略 1x/2x 描述符。
- 按钮、图标这类固定尺寸元素,通常不需要
sizes。加了反而破坏 DPR 适配 - 如果真要配合不同断点下的渲染宽度(比如按钮在移动端宽 32px、桌面端宽 64px),必须改用
w描述符:srcset="btn-32w.png 32w, btn-64w.png 64w",并确保sizes值与 CSS 实际计算出的宽度严格一致 - 验证是否生效?打开 Chrome DevTools → Network 面板 → 刷新 → 筛选 Img → 右键 Copy image src → 粘贴确认 URL 含
@2x或@3x
验证是否真加载了高 DPI 图,别信 devicePixelRatio
window.devicePixelRatio 返回 2 只说明设备支持高 DPI,不代表图片就加载了对应版本。真正决定加载哪张图的是 HTML 结构和浏览器解析逻辑。
- 模拟不同 DPR:DevTools → ⚙️ → Sensors → Device pixel ratio → 改为 1 / 2 / 3,然后**硬刷新(Ctrl+Shift+R)**,普通刷新可能走缓存
- 检查
<img>是否存在且带src:这是兜底必需项,漏掉会导致空白 - 多个
<source></source>的media条件重叠(如(max-width: 768px)和(max-width: 1024px)),浏览器只取第一个匹配项,后面全失效
<img src>。调试时别猜,直接看 Network 面板加载的实际 URL。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











