loading="lazy" 是浏览器原生懒加载方式,但仅对满足全部条件的 生效:不在首屏、未设宽高、非 inline 渲染、不在 或 内,且不位于 中或通过 background-image 加载;需配合正确 srcset 和 sizes 使用,并在 chrome 76+、firefox 75+、safari 15.4+ 才完整支持,旧版 ios/android webview 需 intersectionobserver 兜底。

loading="lazy" 是浏览器原生支持的懒加载方式,开箱即用,但不是“设了就一定生效”——它有明确的适用边界和常见失效场景。
哪些 img 标签能用 loading="lazy"?
只有满足以下全部条件的 <img> 才会被浏览器真正延迟加载:
- 不在首屏(即
getBoundingClientRect().top > window.innerHeight) - 没有设置
width和height属性(部分浏览器会因无法预估布局而跳过懒加载) - 未被 CSS 强制设为
display: block以外的渲染模式(如inline或无样式包裹的文本流中) - 不位于
<picture></picture>或<iframe></iframe>内部(某些旧版 Chromium 表现不稳定)
特别注意:loading="lazy" 对 <img> 在 <svg></svg> 内、或通过 background-image 加载的图片完全无效——这些必须走 JS 方案。
loading="lazy" 和 srcset 能一起用吗?
能,而且必须一起用,否则响应式图片在懒加载下大概率拉取错尺寸。
浏览器在触发懒加载时,会重新解析 srcset + sizes,按当前视口宽度匹配最合适的资源。但前提是:
-
sizes必须写明确(例如sizes="(max-width: 768px) 100vw, 50vw"),不能留空或只写"100vw" -
srcset中的宽度描述符(w)要覆盖目标设备像素比(如1x,2x设备需同时提供400w和800w) - 不要把
src指向大图,否则即使srcset存在,浏览器也可能 fallback 到src
正确写法示例:
<img src="fallback.jpg" srcset="small.jpg 480w, medium.jpg 768w, large.jpg 1200w" sizes="(max-width: 480px) 100vw, (max-width: 768px) 50vw, 33vw" loading="lazy" alt="...">
为什么加了 loading="lazy" 还是首屏全加载?
这是最常被忽略的兼容性事实:Chrome 76+、Firefox 75+、Safari 15.4+ 才完整支持;iOS Safari 直到 15.4(2022 年 3 月发布)才修复对内联 SVG 中 <img> 的支持。
如果你的目标用户包含大量 iOS 14.x 或 Android WebView(尤其微信内置浏览器),loading="lazy" 实际无效。此时必须降级到 IntersectionObserver 方案,并注意:
- 不要依赖
img.complete判断是否已缓存——它在 Safari 中可能返回false即使图片已加载完成 - 观察器回调里要检查
entry.target.dataset.src是否存在且非空,避免重复赋值src - 动态插入的
<img>必须手动调用observer.observe(img),不会自动继承父容器的观察状态
要不要保留 JS 懒加载作为兜底?
要。哪怕只支持现代浏览器,也建议保留轻量级 IntersectionObserver 回退逻辑,因为:
-
loading="lazy"无法控制阈值(比如想在元素还有 200px 进入视口时就开始加载,它只支持固定比例) - 服务端渲染(SSR)页面中,首屏图片若被 CDN 缓存了 HTML,
loading="lazy"可能被静态优化工具误删 - 部分企业内网环境禁用新特性(如某些银行系统强制 IE 兼容模式)
最小可用兜底代码只需 12 行,且可与 loading="lazy" 共存——浏览器会优先走原生逻辑,JS 仅捕获未被接管的元素。











