前端性能优化之图片懒加载原理与实现
字数 979 2025-11-06 12:41:12
前端性能优化之图片懒加载原理与实现
1. 懒加载的概念与价值
懒加载(Lazy Load)是一种延迟加载非关键资源的技术。对于图片而言,指的是只加载当前视口(Viewport)内的图片,而视口外的图片在用户滚动到其位置时再加载。
核心价值:
- 减少页面首次加载的HTTP请求数,提升首屏渲染速度。
- 节省用户流量(尤其是移动端)。
- 减轻服务器压力。
2. 实现原理
懒加载的关键是判断图片是否进入视口。具体步骤:
- 将页面中的图片的
src属性暂存(如放到data-src),初始时src设为空或占位图。 - 监听滚动事件(或使用Intersection Observer API),计算图片与视口的相对位置。
- 当图片进入视口时,将
data-src的值赋给src,触发图片加载。
3. 传统实现(基于滚动事件 + getBoundingClientRect)
步骤1:HTML结构准备
<img data-src="真实的图片URL" src="占位图或空URL" class="lazy-img" />
步骤2:判断图片是否进入视口
通过Element.getBoundingClientRect()获取图片相对视口顶部的位置:
function isInViewport(el) {
const rect = el.getBoundingClientRect();
return rect.top >= 0 && rect.top <= window.innerHeight;
}
注意:可添加缓冲区域(如提前100px加载)以提升体验:
rect.top <= window.innerHeight + 100;
步骤3:滚动监听与加载
const lazyImages = document.querySelectorAll('.lazy-img');
function lazyLoad() {
lazyImages.forEach(img => {
if (img.dataset.src && isInViewport(img)) {
img.src = img.dataset.src; // 触发加载
img.removeAttribute('data-src'); // 避免重复加载
}
});
}
// 初始检查一次
lazyLoad();
// 滚动时防抖优化
window.addEventListener('scroll', throttle(lazyLoad, 200));
防抖/节流:避免滚动事件频繁触发导致性能问题。
4. 现代实现(Intersection Observer API)
Intersection Observer是浏览器原生API,可高效监听元素与视口的交叉状态,无需手动计算位置。
步骤1:创建Observer
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) { // 元素进入视口
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img); // 停止监听已加载的图片
}
});
}, {
rootMargin: '100px', // 提前100px触发加载
});
步骤2:绑定需要懒加载的图片
document.querySelectorAll('.lazy-img').forEach(img => {
observer.observe(img);
});
优势:
- 自动管理交叉检测,无需手动监听滚动。
- 性能更好,避免主线程阻塞。
5. 优化与注意事项
- 占位图策略:使用极小的Base64占位图或CSS背景色避免布局抖动。
- 响应式图片:结合
srcset和sizes属性时,可将真实URL放在data-srcset中。 - SEO友好:确保搜索引擎能抓取到真实图片URL(如通过
<noscript>标签兜底)。 - 错误处理:监听图片加载失败事件,可替换为默认图。
6. 总结
懒加载通过“按需加载”显著提升页面性能,传统方案依赖滚动事件和位置计算,现代方案使用Intersection Observer更简洁高效。实际开发中需结合具体场景选择实现方式,并注意兼容性和用户体验优化。