loading="lazy" 仅对同时满足src属性存在、有可计算高度、不在首屏内、父容器无干扰样式、且不位于<picture>外的<img>生效;常见失效原因包括未设宽高、display:none、浏览器禁用、document.write()注入及与JS懒加载库混用。
loading="lazy" 不是加了就生效的开关,它依赖浏览器对布局、可见性、资源地址的综合判断。用错地方或缺关键条件,Chrome 会直接忽略它,当成普通 <img> 处理。
<img> 能真正触发懒加载只对同时满足以下全部条件的图片有效:
<img> 标签必须有明确的 src(不能只靠 data-src),浏览器需要真实 URL 才能发起延迟请求width 和 height 属性,或 CSS 中设置了固定尺寸(如 height: 200px 或 aspect-ratio: 16/9)transform、opacity: 0、visibility: hidden 等干扰布局可见性判断的样式<picture> 内部——如果用了 <picture>,loading="lazy" 必须写在内部的 <img> 上,而不是 <picture> 标签上loading="lazy" 常见失效原因遇到“加了但图片还是全量加载”,先检查这些硬性限制:
Failed to execute 'observe' on 'IntersectionObserver'?大概率是图片没设宽高,Safari 和部分旧版 Chrome 会直接跳过懒加载逻辑display: none 的容器里?loading="lazy" 会失效——因为浏览器无法预估它何时可能进入视口;改用 visibility: hidden + 固定尺寸可临时绕过document.write() 动态注入内容?现代浏览器已限制该行为,但遗留代码仍可能导致懒加载被跳过不能混用。一旦引入 lozad、LazyLoad.js 这类库,就必须移除所有 loading="lazy" 属性:
立即学习“前端免费学习笔记(深入)”;
loading="lazy" 同时又监听了 IntersectionObserver,可能重复触发请求,导致图片加载两次或卡顿data-src → src 的赋值流程,原生懒加载机制反而会干扰这个过程最易被忽略的一点:懒加载不是“等用户滚到图片才开始下载”,而是浏览器根据滚动预测提前约 1250px 加载——如果你需要更激进的提前量(比如 200px 就加载),loading="lazy" 无能为力,必须换 Intersection Observer 并配 rootMargin。