现代浏览器原生支持懒加载,只需在<img>标签添加loading="lazy"属性即可,该属性仅对<img>和<iframe>有效,兼容Chrome 76+、Firefox 75+、Safari 15.4+。

图片懒加载用 loading="lazy" 就够了
现代浏览器原生支持懒加载,不需要 JS 库或复杂逻辑。只要在 <img> 标签里加 loading="lazy" 属性,浏览器就会自动在图片即将进入视口时才开始下载。
注意:这个属性只对 <img> 和 <iframe> 有效,且在 Chrome 76+、Firefox 75+、Safari 15.4+ 中可用。旧版 Safari(
示例:
<img src="photo.jpg" alt="风景" loading="lazy">
-
loading="eager"强制立即加载(默认行为,通常不用显式写) -
loading="lazy"延迟加载 —— 只需这一行,无 JS、无监听、无 polyfill - 不要和
srcset或picture冲突:它们可共存,loading仍生效
什么时候不能只靠 loading="lazy"
原生懒加载依赖浏览器的 Intersection Observer 实现,它在以下场景会失效或表现异常:
立即学习“前端免费学习笔记(深入)”;
- 页面有大量图片但初始
height为0或未设宽高 —— 浏览器无法预估位置,可能跳过懒加载甚至不加载 - 图片在
display: none容器内,或被 CSStransform移出视口 —— 部分浏览器无法正确触发 - 需要更精细控制(比如滚动中提前 200px 加载,或加载失败后 fallback)
- 必须兼容 IE 或老版本移动端 WebView(如微信 7.x 内核)
这些情况就得上 JS 方案,但不是从零写 —— 优先用轻量库,比如 lozad.js(仅 1KB),它只监听元素可见性,不接管 src 替换逻辑,可控性强。
手写 JS 懒加载的关键三步
如果必须自定义逻辑(比如要加 loading 占位图、错误重试、或配合 CMS 动态生成 data-src),核心就三件事:
- 把真实地址放
data-src,src先设为空或占位图:<img src="placeholder.svg"> - 用
IntersectionObserver监听可见性,回调里把data-src赋给src,再调用observer.unobserve(el)防重复触发 - 给
img绑定onload和onerror,失败时可降级显示文字或重试
别手动计算 scrollTop + offsetTop —— 性能差还容易漏帧;IntersectionObserver 是浏览器优化过的,直接用。
loading="lazy" 和 JS 方案混用的风险
常见错误是同时写 loading="lazy" 和 JS 懒加载逻辑,结果图片被加载两次:一次由浏览器触发,一次由 JS 触发。
解决办法很简单:
- 要么全用原生
loading="lazy"(推荐大多数静态页) - 要么 JS 方案里统一移除
loading属性:img.removeAttribute('loading'),避免干扰 - 服务端渲染时注意:若 SSR 输出了
src,再 JS 懒加载就失去意义 —— 此时应确保 SSR 不输出真实src,只留data-src
真正难的不是实现,而是判断哪些图该懒、哪些不该懒 —— 比如首屏 banner 图硬加 loading="lazy",反而拖慢关键渲染。



















