loading="lazy"必须直接写在<img>标签中才生效,仅对常规图片有效,不支持<picture>或<source>;首屏关键图应设为eager,兼容性差时需用IntersectionObserver降级。

img 标签怎么加 loading="lazy" 才生效
必须加在 <img> 标签里,且只对非内联、非背景图的常规图片起作用。浏览器原生懒加载只认这个属性,不依赖 JS。
- 正确写法:
<img src="photo.jpg" loading="lazy" alt="描述"> -
loading值只有三个:"eager"(立即加载)、"lazy"(懒加载)、空值或非法值会退化为"eager" - 不支持
<picture>或<source>标签单独设loading,得写在最外层<img>上 - 服务端渲染或 CMS 输出时,如果模板没透出该属性,前端 JS 补加无效——浏览器只在解析 HTML 阶段读取该属性
哪些图片不该加 loading="lazy"
首屏关键图加了反而 hurt 性能:浏览器可能误判可视区,导致白屏或闪烁;尤其在 SSR + 客户端 Hydration 场景下更明显。
- 首页 banner、logo、核心按钮图标等明确在首屏的
<img>,应设loading="eager"或直接不写 - 高度不确定的图片(比如宽高靠 CSS aspect-ratio 或 JS 动态撑开)容易被懒加载跳过首次渲染,出现“图片突然掉下来”
- 部分安卓 WebView(如旧版微信 X5)不支持该属性,加了等于没加,但也不报错——别指望它兜底
兼容性差怎么办:用 IntersectionObserver 手动降级
Chrome 76+、Firefox 75+、Safari 15.4+ 原生支持 loading="lazy";IE 和老 Edge 全不支持,必须 JS 降级。
- 不要用
getBoundingClientRect()轮询判断是否进入视口——性能差、抖动大 - 用
IntersectionObserver监听,触发后才设置src或srcset,同时移除占位符类名 - 注意:observer 的
rootMargin建议设为"200px",提前加载避免滚动过快时空白 - 示例关键逻辑:
img.dataset.src存真实地址,observer.observe(img)后赋值img.src = img.dataset.src
和 srcset、sizes 配合时要注意什么
loading="lazy" 和响应式图片是正交功能,但参数协同不好会引发重复请求或尺寸错乱。
立即学习“前端免费学习笔记(深入)”;
-
sizes必须存在且合理,否则 lazy 加载时浏览器无法预估图片宽度,可能选错srcset中的资源 - 避免在
srcset里混用不同 DPR 的图却没配sizes,懒加载阶段 DPR 判断可能滞后 - Webpack/Vite 构建时若用了 image-minimizer-plugin,确保未把
data-src类字段误压缩——有些插件会删掉非标准属性 - 开发环境用 Chrome DevTools 的
Network → Disable cache+ 慢速 3G 模拟,才能真实观察懒加载时机
loading 属性变量,或者 CMS 富文本编辑器自动过滤了该字段。不是代码写了就一定进 DOM。











