intersection observer 是浏览器原生异步 api,用于监听元素是否进入视口;它不阻塞主线程、不触发重排、支持 rootmargin 提前加载,且仅在 isintersecting 为 true 时精准触发,天然适配图片懒加载“按需加载”核心诉求。

Intersection Observer 是什么,为什么适合图片懒加载
它不是轮询或 scroll 事件的替代品,而是浏览器原生提供的异步监听元素是否进入视口的机制。相比 scroll + getBoundingClientRect(),它不触发重排、不阻塞主线程、支持根容器偏移(rootMargin),且能精确控制触发时机。
懒加载的核心诉求是:图片真正要被用户看到时才请求资源。Intersection Observer 天然匹配这个逻辑——只有当 isIntersecting === true 时才开始加载。
如何用 Intersection Observer 绑定 img 标签并加载真实 src
关键在于把占位图(如 data-src)延迟赋给 src,并在进入视口后触发加载。注意:必须在回调中检查 isIntersecting,否则离开视口时也会触发(比如滚动过快导致短暂触发又离开)。
- 给所有待懒加载的
<img>添加data-src属性,src可设为空或指向 1×1 占位图 - 创建
IntersectionObserver实例,配置rootMargin: '50px'提前 50px 开始加载,避免滚动停顿导致白屏 - 在
callback中遍历entries,对每个entry.isIntersecting === true的元素,取entry.target.dataset.src赋值给src,然后调用observer.unobserve(entry.target)防止重复触发
const lazyImages = document.querySelectorAll('img[data-src]');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, { rootMargin: '50px' });
lazyImages.forEach(img => observer.observe(img));
常见错误:图片加载失败后不降级、未处理 loading 状态、重复 observe 同一元素
实际项目中,img.src 赋值后可能 404 或网络中断,此时页面留白。同时,用户快速滚动可能让同一张图多次进入/离开视口,若没调用 unobserve,会反复尝试加载。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 务必在
img.onload和img.onerror中做状态清理:成功则移除data-src;失败可 fallback 到默认图或加 class 标记 - 不要在
callback外直接操作 DOM 属性,比如提前写img.src = '',这会触发浏览器预加载行为,反而绕过懒加载 - 如果 img 是动态插入的(如分页加载),需在插入后手动调用
observer.observe(img),不能只靠初始化时的querySelectorAll
兼容性与性能补充:Safari 12.1+ 支持,老版本需降级方案
IE 完全不支持,iOS Safari getBoundingClientRect() + scroll 轮询作为 fallback,但要注意节流和只监听可见区域内的元素。
更轻量的做法是:检测 'IntersectionObserver' in window,不支持时直接批量设置所有 src —— 对首屏影响小,且避免维护两套逻辑。现代项目中,只要目标用户基本覆盖 Safari 13+/Chrome 74+,就可以放心用原生 API。
真正容易被忽略的是:观察器实例本身不会自动销毁,如果页面长期存在(如 SPA),且懒加载区域频繁切换,应保留 observer 引用并在合适时机调用 observer.disconnect(),否则可能造成内存滞留。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










