srcset不是fallback,而是浏览器根据DPR、视口宽度等自主择优加载候选资源;真正兜底的只有src,它必须存在、可访问且兼容(如JPG/PNG)。

srcset 不是 fallback,是浏览器自主择优加载
很多人误以为 srcset 是“这张图加载失败就换下一张”,其实完全不是。它没有重试或降级机制,只是给浏览器提供一组候选资源,由浏览器根据设备像素比(DPR)、视口宽度、网络条件(如 fetchpriority)等自动选一个最合适的加载——选中哪个,就只加载那个;其余全被忽略。失败了也不会切到另一个,只会留白或显示破损图标。
真正起兜底作用的,永远只有 src 属性本身。所以:src 必须存在、必须可访问、必须格式兼容(如 .jpg 或 .png),否则整个降级链就断了。
-
srcset中混用w和x描述符(比如"a.jpg 400w, b@2x.jpg 2x")会导致整个属性被浏览器忽略 - 只写
srcset不配sizes,Chrome 会按100vw估算,Safari 可能直接跳过——结果就是小屏手机也加载 1920w 大图 -
sizes的值必须反映图片**实际渲染宽度**,不是容器 CSS 宽度,也不是设计稿宽度;常见正确写法:sizes="(max-width: 768px) 100vw, 50vw"
为什么写了 srcset 却总加载错尺寸?
根本原因:浏览器算错了“这张图该占多宽”,于是选错了 srcset 里的项。它依赖 sizes 告诉它“在不同断点下,这张图会渲染成多宽”,再结合当前 DPR 和视口宽度,反推出应加载哪张。
例如你写了 sizes="(max-width: 480px) 100vw",但实际页面中该图被 CSS 限制在 max-width: 320px 且有内边距,浏览器仍按 100vw(即 480px)去匹配 srcset 中的 480w 项——但原图真实宽度其实是 320px,结果加载后被拉伸或模糊。
- 用 Chrome DevTools Network 面板禁用缓存后刷新,右键图片 → “Copy” → “Copy response”,确认返回尺寸是否匹配
srcset中声明的w值 -
srcset中每个w值必须等于对应图片文件的真实像素宽度(不能是“大概”或“设计稿尺寸”) - 如果页面用了
transform: scale()或未设,media查询可能失效,间接导致sizes计算偏移
srcset + sizes 在旧浏览器里怎么活下来?
IE11、旧版 Android WebView 等不支持 srcset 和 sizes,它们会直接忽略这两个属性,只加载 src。所以 src 不仅是兜底,更是这些环境下的唯一来源。
这意味着:src 不能是占位图、不能是空字符串、不能指向挂掉的 CDN 路径。它得是一张真实可用、体积可控、格式普适的图——比如托管在主站同域下的 800w 主图,或 SSR 渲染出的 LQIP 模糊图。
- 避免把
src写成data:image/gif;base64,...后托管在不可靠第三方服务上;一旦服务宕机,IE 用户看到的就是空白 - 不要指望
loading="lazy"能救场:不支持该属性的浏览器会直接忽略data-src,只加载src;若src不可用,照样白屏 - 如果项目必须兼容 IE,
不是替代方案(IE 完全不支持),只能老老实实用单张src+ 合理尺寸 +width/height或aspect-ratio防抖动
容易被忽略的布局崩溃点:没设宽高或 aspect-ratio
哪怕 srcset 和 sizes 全对,只要图片没预设尺寸,加载前容器高度为 0,加载完成瞬间撑开布局,文字跳、按钮移、CLS 直接爆表——这不是降级问题,是基础排版缺失。
width 和 height 属性在现代布局中虽不强制,但仍是防抖动最轻量、最可靠的方式;aspect-ratio 是更灵活的替代,但 Safari 15.4 以下不支持,需配合 fallback。
- 用
width/height时,值应与src图片原始宽高一致(不是响应式后的尺寸) - 若用
aspect-ratio: 4/3,确保后备方案(如padding-top: 75%的伪元素)已就位 - 绝对不要用
display: none包裹图片容器——Safari 和多数 Android WebView 会跳过该元素,后续show()也无效
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











