根本原因是sizes未告知浏览器图片实际渲染宽度,导致浏览器默认按100vw估算并加载最大图;必须为每个断点精确匹配CSS真实宽度,且srcset中w值须与原图真实像素宽完全一致。

srcset + sizes 不生效,浏览器还是加载了最大图
根本原因不是属性写错了,而是 sizes 没告诉浏览器“这张图实际占多宽”,导致浏览器默认按 100vw 估算——哪怕你写了 srcset="small.jpg 320w, large.jpg 1200w",它也只会选 large.jpg。这不是 bug,是规范行为。
- 必须为每个断点写明 CSS 中该图容器的真实宽度,比如容器在移动端被设为
max-width: 300px,那sizes就得是sizes="(max-width: 768px) 300px, 50vw" -
srcset中的320w必须和原图真实宽度完全一致(用file photo.jpg或identify photo.jpg验证),写成300w或320(漏掉w)都会让整个srcset失效 - 开发阶段禁用缓存后刷新,在 Network 面板右键图片 → “Copy” → “Copy response”,确认返回的确实是目标尺寸图,否则说明匹配逻辑没走通
为什么 IE11 或老 Android WebView 加载的是小图甚至空白
srcset + sizes 是现代方案,IE11、Android 4.4 WebView 等根本不解析这两个属性,它们只认 src。如果你把 src 指向一张小图(比如 thumb.jpg),旧浏览器就永远卡在小图;如果 src 是空或 404,就直接白屏。
-
src必须指向一张**静态、高可用、兼容性广**的图,通常是中等分辨率的.jpg或.png,比如/img/photo-fallback.jpg - 不要用相对路径如
./photo.jpg,上线后路由重写易 404;统一用根路径或 CDN 绝对地址 - 若需强兼容,
是更稳妥的选择,但要注意:IE 完全忽略,只渲染内部—— 所以这个src更不能出错
加载后图片拉伸、布局跳动,怎么定位
这不是 CSS 写错了,是不同 srcset 项对应的原图 **intrinsic size(固有像素宽高)不一致**。浏览器按第一张加载图的 EXIF 尺寸计算容器,切到另一张时发现宽高变了,立刻重排。
- 用命令行检查:
file small.jpg和file large.jpg,输出里都必须明确含类似800 x 450;如果显示data或no dimensions,说明元数据丢失 - 修复 JPEG 元数据:
exiftool -ImageWidth=800 -ImageHeight=450 large.jpg - 生成时强制写死尺寸:
convert -resize 800x450\! input.png output.jpg(注意末尾\!) - 终极保险:放弃依赖图片自身尺寸,用
style="aspect-ratio: 16/9; width: 100%;"锁定容器比例
onerror 替换 src 后又触发一次 error,怎么办
这是最常踩的坑:onerror 只管“当前 src 加载失败”,不管新 src 是否可靠。如果 fallback 图也 404,就会再次触发 onerror,形成无限循环请求,拖垮页面。
- 必须在替换前加 guard 条件,例如:
onerror="if (!this.src.includes('fallback')) this.src='/img/fallback.jpg'; this.onerror=null;" - 更稳的做法是 fallback 到内联资源:
this.src='data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PC9zdmc+'; - 不要在
onerror里再加载一个未压缩的大图——fallback 图必须是已压过、体积小、CDN 缓存命中的 WebP 或 SVG
真正难的不是写对属性,是确保每张图的原始像素尺寸、服务器响应头、CDN 缓存策略、CSS 布局宽度全部对齐。漏掉其中一环,降级就变成静默白屏。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











