什么是图像的懒加载?如何实现?
·
什么是图像的懒加载?如何实现?
图像的懒加载是一种优化网页性能的技术,它延迟加载视口之外的图像,直到用户滚动到它们即将出现的位置时才加载。这样可以减少初始页面加载时的网络请求和数据传输量,加快首屏渲染速度,节省用户流量。

原理
懒加载的核心思想是:将图像的真正的URL存储在自定义属性(例如 data-src)中,而 <img> 的 src 属性初始设置为占位图或留空。 然后通过监听滚动事件或使用更现代的 Intersection Observer API,监测图像元素是否进入视口。一旦元素进入视口,就将 data-src 的值赋给 src,触发浏览器加载真实的图像。
实现方式
1.浏览器默认支持的懒加载

使用浏览器原生 loading="lazy"(最简单),HTML5 提供了原生的图片懒加载属性
<img src="image.jpg" loading="lazy" alt="..." />
- 优点:无需额外代码,浏览器自动处理。
- 缺点:兼容性稍差(不支持较旧浏览器),且无法自定义加载阈值。
2. 基于事件的懒加载(传统方式)
- 步骤:
- 获取所有需要懒加载的图像元素(例如带有
data-src属性的<img>)。 - 监听
scroll、resize和orientationchange事件。 - 在事件处理函数中,遍历这些图像,通过
getBoundingClientRect()判断其是否进入视口(例如top < window.innerHeight且bottom > 0)。 - 如果进入视口,则将
data-src的值赋给src,并将图像从待加载列表中移除或标记为已加载。 - 注意使用节流(throttle)优化高频事件,避免性能问题。
- 获取所有需要懒加载的图像元素(例如带有
- 缺点:需要手动计算位置,且滚动事件触发频繁,性能较差。
3. 基于 Intersection Observer 的懒加载(现代推荐)
- 原理:Intersection Observer 异步观察目标元素与祖先元素或视口的交叉状态,当元素进入或离开视口时会触发回调,无需手动监听滚动事件。
- 步骤:
- 创建一个 Intersection Observer 实例,配置根元素(通常为
null表示视口)和阈值(例如threshold: 0.1表示元素出现 10% 时触发)。 - 使用
observer.observe(img)对每个待懒加载的图像开始观察。 - 在回调函数中,遍历所有发生交叉变化的条目(
entries)。对于每个条目,如果isIntersecting为true(即进入视口),则加载真实图像(将data-src赋给src),然后停止观察该元素(observer.unobserve(img))。
- 创建一个 Intersection Observer 实例,配置根元素(通常为
- 优点:性能更好,代码简洁,且能自动处理动态添加的元素。
示例代码(Intersection Observer)
<img class="lazy" data-src="real-image.jpg" src="placeholder.jpg" alt="...">
const lazyImages = document.querySelectorAll('img.lazy');
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy'); // 可选:移除标记
observer.unobserve(img); // 停止观察
}
});
}, {
rootMargin: '0px 0px 200px 0px', // 可选:提前加载(例如距离视口底部200px时触发)
threshold: 0.01
});
lazyImages.forEach(img => observer.observe(img));
注意事项
- 占位图:初始
src可设置为极小占位图或 Base64 图像,避免空白闪烁。 - 尺寸设置:为
<img>设置明确的width和height属性,或使用 CSS 预留空间,防止图像加载后造成页面布局偏移。 - 加载失败处理:监听
error事件,加载失败时显示默认图片。 - 兼容性:Intersection Observer 在现代浏览器中支持良好,但如需要兼容旧版浏览器,可引入 polyfill 或回退到事件监听方式。
React项目中的使用情况
使用 Intersection Observer 自定义实现(推荐)
封装一个 LazyImage 组件,利用 Intersection Observer 监听图片是否进入视口,进入后再加载真实图片。
示例:LazyImage 组件
import React, { useEffect, useRef, useState } from 'react';
const LazyImage = ({ src, placeholder, alt, ...props }) => {
const imgRef = useRef();
const [loaded, setLoaded] = useState(false);
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
// 进入视口,加载真实图片
const img = entry.target;
img.src = src;
setLoaded(true);
observer.unobserve(img); // 停止观察
}
});
},
{
rootMargin: '200px 0px', // 提前 200px 加载
threshold: 0.01,
}
);
if (imgRef.current) {
observer.observe(imgRef.current);
}
// 清理 observer
return () => {
if (imgRef.current) {
observer.unobserve(imgRef.current);
}
};
}, [src]); // 依赖 src,当 src 变化时重新观察
return (
<img
ref={imgRef}
src={placeholder} // 初始占位图
alt={alt}
{...props}
/>
);
};
export default LazyImage;
使用方式
<LazyImage
src="real-image.jpg"
placeholder="placeholder.jpg"
alt="description"
/>
1.2 使用第三方库
- react-lazyload:老牌库,基于滚动事件监听。
- react-intersection-observer:提供
useInViewHook,简化 Intersection Observer 的使用。 - react-lazy-load-image-component:功能丰富,支持占位、淡入效果等。
例如使用 react-intersection-observer:
npm install react-intersection-observer
import { useInView } from 'react-intersection-observer';
const LazyImage = ({ src, placeholder, alt }) => {
const { ref, inView } = useInView({
triggerOnce: true,
rootMargin: '200px 0px',
});
return (
<img
ref={ref}
src={inView ? src : placeholder}
alt={alt}
/>
);
};
Nextjs中如何实现
Next.js 提供的 next/image 组件是图像优化的终极方案,它默认开启了懒加载
import Image from 'next/image';
export default function Page() {
return (
<>
{/* 首屏大图:急切加载,高优先级 */}
<Image src="/hero.jpg" alt="Hero" width={1200} height={600} priority loading="eager" />
{/* 下方图片:默认懒加载 */}
<Image src="/gallery/image1.jpg" alt="Gallery 1" width={800} height={600} />
</>
);
}
如何正确实现SEO友好的懒加载
为了充分利用懒加载的优势并规避风险,可以遵循以下最佳实践:
- 区别对待首屏与下方内容:
- 首屏重要图片:永远不要对它们使用懒加载。应使用
loading="eager",并为最重要的图片(如LCP元素)加上priority属性。 - 首屏下方的图片:放心地使用懒加载。
- 首屏重要图片:永远不要对它们使用懒加载。应使用
- 始终设置图片尺寸:为
<img>标签加上width和height属性。这能为图片预留空间,防止懒加载导致页面布局突然变化。 - 检查最终实现效果:如果使用了复杂的懒加载库,可以用Google Search Console的"网址检查"工具,查看Google看到的渲染后HTML,确保图片的URL正确出现在
src属性中。
总结
- 通过懒加载,可以显著提升长页面的加载速度和用户体验,是前端性能优化的常用手段。
- 需要注意的是图像懒加载对SEO(搜索引擎优化)的影响是双面的。关键在于如何实现它:正确的实现是强大的优化工具,而错误的实现则可能损害你的搜索排名。
更多推荐
所有评论(0)