src必须指向真实可用的占位图,否则不支持loading="lazy"的浏览器会白屏;data-src须静态写入html作为降级保底;css隐藏或js加载失败将导致无提示白屏。

只加 loading="lazy" 但没设可用的 src,图片在不支持该属性的浏览器里大概率白屏——这不是“没生效”,是压根没给降级路径。
为什么 src 必须指向一个真实可用的占位图
浏览器对 loading="lazy" 的处理是“存在即使用,不存在就忽略”,它不会自动把 data-src 赋给 src。如果 src 是空、src="" 或指向 404 路径,降级后就是一张透明/空白区域。
-
src应该是一个小体积(1–2KB)、尺寸匹配的真实占位图,比如 1px GIF、LQIP base64 或纯色 SVG - 不能用
src="data:image/gif;base64,R0lGODdhAQABAPAAAP8AAAAAACwAAAAAAQABAAACAkQBADs="这类通用 GIF——部分 Android WebView 解析失败,留白 - 服务端渲染(SSR)时,首屏图片的
src必须可访问,不能依赖 JS 后续补全,否则断网即空白
data-src 不是可选字段,而是必须静态存在于 HTML 中
data-src 是懒加载的“真实目标”,但它不是 JS 动态塞进去的变量;它是降级链上最后一环的保底地址。
- 必须写死在 HTML 源码里:
<img src="placeholder.jpg" loading="lazy"> - 如果靠 JS 异步请求 JSON 再拼
data-src,网络失败时这个属性根本不存在,JS 也无从 fallback - 注意:Safari 对
onerror+loading="lazy"组合支持不稳定,别指望靠onerror补救data-src缺失
CSS 层面的隐形降级陷阱
很多团队调通了 JS 逻辑,却在 CSS 上栽跟头——有些样式会让 loading="lazy" 直接失效,且毫无提示。
-
display: none的容器内图片,在 Safari 和多数 Android WebView 中永远不触发懒加载,即使之后display: block也不会补载 -
opacity: 0或visibility: hidden没问题,但若 JS 断网未执行,这些样式会让用户看到“不可见的空框” - 没设
aspect-ratio或宽高,图片加载前盒模型塌陷,文字上推重排——这不是加载问题,是布局没兜住
断网时 JS 初始化代码必须内联且带兜底
如果懒加载逻辑全靠外部 <script src="lazy.js"></script>,那这个请求失败,所有图片就卡死。
- 核心初始化代码(含
IntersectionObserver创建和 fallback 遍历)必须内联进<script></script>标签 - 必须做存在性检测:
if ('IntersectionObserver' in window),但检测失败时要立刻执行:document.querySelectorAll('img[data-src]').forEach(i => i.src = i.dataset.src) - 关键图片(如商品主图、头图)直接跳过懒加载:不写
loading="lazy",也不设data-src,src写死真实地址
真正麻烦的从来不是“怎么放一个灰色方块”,而是当 src 和 data-src 的语义边界模糊、CSS 隐藏了加载状态、或 JS 加载链断裂时,你根本收不到任何报错——只有白屏,和用户默默关掉页面。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











