图片懒加载(Lazy Loading)是一种网页优化技术,当图片需要显示时才加载,避免了不必要的流量消耗和服务器带宽浪费。
当页面包含大量图片时,浏览器会逐一发送 GET 请求获取每张图片的数据流,这会消耗用户的流量和服务器的带宽。无论是在 PC 端还是移动端,屏幕尺寸都是有限的,一次无法显示所有图片。因此,对于那些不在视口中的图片,我们无需立即加载,待用户滚动页面使图片进入可视区域时再进行加载。
基本原理
懒加载的概念非常简单:当页面上的图片进入可视区域时才加载它们。传统的懒加载方法通过监听滚动事件实现,但这种方法性能较差,需要频繁计算滚动位置。Intersection Observer API 则提供了一种更高效的解决方案。
懒加载的实现过程如下:
- 给图片设置一个占位图。
html
<img src="占位图.png">
- 使用
data-src
属性保存真实图片的地址。
html
<img src="placeholder.png" data-src="real-image.jpg">
- 当图片进入可视区域时,将
data-src
的值赋给src
属性,从而加载真实图片。
传统方案:监听滚动事件
传统方法通过监听滚动事件来实现懒加载:
javascript
window.addEventListener("scroll", () => {
const imgs = document.querySelectorAll('img');
imgs.forEach(img => {
const rect = img.getBoundingClientRect();
if (rect.top < document.body.clientHeight) {
img.src = img.dataset.src;
}
});
});
这种方法需要频繁计算滚动位置,性能较差,还需使用防抖函数。
新方案:Intersection Observer API
Intersection Observer API 是浏览器原生提供的,用于异步检测目标元素与视口或父元素是否产生交叉。它的优势在于提高性能和简化代码实现。
实现代码
以下是使用 Intersection Observer 实现图片懒加载的完整代码:
javascript
let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
observer.unobserve(img);
}
});
}, {
root: null,
rootMargin: "0px",
threshold: 0.1
});
document.querySelectorAll('img').forEach(img => observer.observe(img));
代码解析
IntersectionObserver
构造函数接受两个参数:回调函数和配置对象。- 回调函数处理所有进入视口的图片,将
data-src
赋值给src
,并取消观察。 root
为null
表示视口为根元素。threshold
为0.1
表示当图片 10% 可见时触发回调。
效果
优势
- 高性能:只有在目标元素与视口交叉时才会触发回调。
- 简洁:不需要计算滚动距离,代码简洁明了。
- 兼容性好:现代浏览器都支持 Intersection Observer。