loading="lazy"是浏览器原生懒加载开关,chrome 76+等主流浏览器支持,需直接写在标签上并配合width/height属性;首屏图应设为eager或不加该属性,避免白屏。

loading="lazy" 是浏览器原生控制图片加载时机的开关
它不是 JS 插件,也不依赖任何库,是浏览器自己识别并执行的策略。只要写在 <img> 标签里,Chrome 76+、Firefox 75+、Safari 15.4+ 就会按需发起请求——不进视口就不发 HTTP 请求,连 DNS 查询和 TCP 连接都省了。
注意:loading 属性只对常规 <img src="..."> 生效,<picture></picture> 和 <source></source> 单独设它没用;必须直接写在最外层 <img> 上,服务端模板或 CMS 富文本若过滤了该属性,就等于白写。
loading 值只有三个:eager、lazy、空值或非法值
loading="eager" 表示立即加载,首屏关键图(比如 banner、logo)必须显式声明或干脆不写这个属性(因为默认就是 eager);loading="lazy" 表示延迟加载;其他任何值(包括 loading=""、loading="auto"、loading="off")都会退化为 eager。
常见错误现象:
- 写了
loading="lazy"但图片还是首屏全加载——可能是图片离首屏太近,浏览器提前触发了(尤其在 4G/光纤下) - 页面底部图片滚动到才闪一下才出现——说明懒加载生效了,但没配
width/height,导致重排或占位塌陷 - 用
<picture><source></source></picture>包裹,却只给<source></source>加loading——完全无效,必须加在<img>上
为什么不能所有图片都加 loading="lazy"
首屏图加了 lazy,可能被浏览器当成“非关键资源”延后加载,造成 banner 白屏或 FOUC;瀑布流、无限滚动场景中,用户快速下滑时,lazy 触发滞后,会出现明显“图片逐个弹出”的割裂感。
更稳妥的做法是分层处理:
- 首屏内图片:不写
loading或显式loading="eager" - 首屏下方 1–2 屏区域:用
IntersectionObserver配rootMargin: "0px 0px 300px 0px"提前加载,避免空白 - 明显远离首屏的图片(如页脚、联系信息旁):放心用
loading="lazy"
另外,decoding="async" 和 loading="lazy" 组合意义不大——解码异步化对懒加载图片几乎没感知,优先优化尺寸、格式(WebP/AVIF)和 CDN 缓存更实在。
IE 和老 Edge 不支持,降级方案要真能跑
原生 loading 在 IE 和 Edge ≤18 中完全不识别,必须 JS 降级。别用只检测 "loading" in HTMLImageElement.prototype 的简单判断——有些 polyfill 库(比如 lazysizes)会主动 patch 这个判断,但实际行为仍受限于 IntersectionObserver 支持情况。
真正可用的降级逻辑是:
- 先检查
IntersectionObserver是否可用(比loading兼容性还差一点,Edge 15+ 才支持) - 不可用时,回退到节流 +
getBoundingClientRect()手动计算位置(注意移动端缩放、iframe 嵌套等边界) - 所有懒加载图片初始
src必须为空或占位图,真实地址存在data-src里,否则降级代码读不到目标 URL
最容易被忽略的一点:服务端渲染(SSR)或静态站点生成(SSG)时,如果构建流程没把 loading 属性注入到最终 HTML,那客户端再怎么写 JS 也补不回来——得从模板层确认字段透出。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











