IntersectionObserver API 是实现 JavaScript 懒加载最简洁高性能的方案,无需监听 scroll/resize、不触发重排重绘、浏览器原生支持,兼容主流现代浏览器,核心是在元素进入视口时异步加载资源。

用 IntersectionObserver API 实现 JavaScript 懒加载,是目前最简洁、高性能的方案。它不需要监听 scroll 或 resize 事件,不触发重排重绘,浏览器原生支持,兼容性也已覆盖主流现代浏览器(Chrome 51+、Firefox 55+、Safari 12.1+、Edge 79+)。
懒加载的核心逻辑:只在元素进入视口时才加载资源
传统做法常通过监听页面滚动,反复计算元素位置(getBoundingClientRect),既消耗 CPU,又容易因频繁触发导致卡顿。IntersectionObserver 则交由浏览器底层异步监听,只有当目标元素真正与视口产生交叉(或满足阈值)时,才执行回调,大幅降低性能开销。
- 无需手动节流(throttle)或防抖(debounce)
- 不阻塞主线程,回调在空闲时段执行(可配合 requestIdleCallback 进一步优化)
- 支持监听元素是否“离开”视口(例如用于视频暂停、广告曝光统计)
基础用法:三步完成图片懒加载
以 img 标签为例,假设图片真实地址存在 data-src 属性中:
-
标记待加载元素:
-
创建观察器:设置
rootMargin提前触发(如"100px"表示元素距离视口还有 100px 就开始加载) -
响应交叉状态:在回调中替换
src,并调用unobserve()避免重复加载
相比 getBoundingClientRect + scroll 的明显优势
旧方法需绑定 scroll 事件,每次滚动都触发计算,即使元素远在视口外;而 IntersectionObserver:
立即学习“Java免费学习笔记(深入)”;
- 浏览器内部用更高效的方式追踪几何变化(部分基于合成层信息)
- 天然支持 iframe 内容的交叉检测(只要同源)
- 可精确控制触发时机(
threshold支持数组,如[0, 0.25, 0.5, 0.75, 1]) - 支持监听祖先容器(
root选项),不局限于浏览器视口
简单兼容处理与注意事项
对不支持 IntersectionObserver 的老浏览器(如 IE),可用 polyfill(w3c 官方提供)或降级为 scroll 方案。实际使用中注意:
- 确保 lazy 元素有明确高度,避免加载时页面跳动(可用 aspect-ratio 或占位图)
- 动态插入的元素需重新调用
observe() - 慎用
root: null(默认监听视口),若设为某个容器,要确认其有 overflow 和定位上下文











