图片懒加载的核心是只在图片即将进入视口时才加载其真实地址,通过scroll监听+getboundingclientrect判断或intersectionobserver实现,辅以防抖、错误处理、淡入动画和响应式适配。

图片懒加载的核心是:只在图片即将进入视口时才加载它的 src,避免初始加载大量图片拖慢首屏。用 JavaScript 的事件机制实现,关键靠 scroll 监听 + 元素位置判断,再配合防抖或 IntersectionObserver 提升性能。
用 scroll + getBoundingClientRect 实现基础版
适合理解原理或兼容老浏览器(如 IE)。给 window 绑定 scroll 事件,遍历所有待懒加载的 <img>,检查是否进入视口:
- 给每张懒加载图设置
data-src存真实地址,src先为空或占位图 - 在 scroll 回调中调用
el.getBoundingClientRect(),获取元素相对于视口的 top/bottom 值 - 若
rect.top 0,说明元素部分可见,触发加载 - 加载后移除监听目标(比如打上 loaded 类),避免重复执行
必须加防抖,否则滚动卡顿
原生 scroll 事件触发极频繁(每像素都可能触发),不加限制会导致性能暴跌。推荐用定时器防抖:
- 声明一个
let timer = null - 每次 scroll 触发时先
clearTimeout(timer),再timer = setTimeout(checkImages, 100) - 100ms 延迟足够捕捉滚动停止,又不会明显延迟加载
- 也可用
requestAnimationFrame更精准,但防抖已满足大多数场景
推荐用 IntersectionObserver(现代标准)
它由浏览器原生优化,不绑定 scroll、不强制重排重绘,性能远超手动监听:
- 创建实例:
const io = new IntersectionObserver(callback, { threshold: 0.1 }) -
threshold: 0.1表示元素 10% 进入视口就触发;设为0则只要沾边就加载 - 对每张 img 调用
io.observe(img),回调中通过entries拿到isIntersecting和target - 加载完成后调用
io.unobserve(img),避免持续监听已加载的图
补充细节提升体验
实际项目中还需考虑这些:
- 加载失败时显示错误占位图,并记录日志:
img.onerror = () => { img.src = '/error.png'; } - 给 img 加
loading="lazy"属性作为后备(现代浏览器自动处理,但不依赖 JS) - 首次加载可加淡入动画:
img.style.opacity = 0; img.onload = () => { img.style.transition = 'opacity .3s'; img.style.opacity = 1; } - 服务端配合:用
srcset+sizes实现响应式图片,懒加载时一并设置
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











