react 实现图片懒加载
使用 Intersection Observer API
Intersection Observer API 是浏览器原生支持的 API,可以高效地监听元素是否进入视口。这种方法性能较好,适合现代浏览器。
import React, { useEffect, useRef, useState } from 'react';
const LazyImage = ({ src, alt, placeholder }) => {
const [isLoaded, setIsLoaded] = useState(false);
const imgRef = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setIsLoaded(true);
observer.unobserve(entry.target);
}
});
});
if (imgRef.current) {
observer.observe(imgRef.current);
}
return () => {
if (imgRef.current) {
observer.unobserve(imgRef.current);
}
};
}, []);
return (
<img
ref={imgRef}
src={isLoaded ? src : placeholder}
alt={alt}
style={{ opacity: isLoaded ? 1 : 0.5, transition: 'opacity 0.3s' }}
/>
);
};
export default LazyImage;
使用自定义滚动事件监听
对于不支持 Intersection Observer API 的旧浏览器,可以通过监听滚动事件实现懒加载。需要注意节流或防抖以避免性能问题。
import React, { useEffect, useRef, useState } from 'react';
const LazyImage = ({ src, alt, placeholder }) => {
const [isLoaded, setIsLoaded] = useState(false);
const imgRef = useRef(null);
const checkIfInView = () => {
if (imgRef.current) {
const rect = imgRef.current.getBoundingClientRect();
const isVisible = rect.top <= window.innerHeight && rect.bottom >= 0;
if (isVisible) {
setIsLoaded(true);
window.removeEventListener('scroll', checkIfInView);
}
}
};
useEffect(() => {
window.addEventListener('scroll', checkIfInView);
checkIfInView(); // 初始检查
return () => {
window.removeEventListener('scroll', checkIfInView);
};
}, []);
return (
<img
ref={imgRef}
src={isLoaded ? src : placeholder}
alt={alt}
style={{ opacity: isLoaded ? 1 : 0.5, transition: 'opacity 0.3s' }}
/>
);
};
export default LazyImage;
使用第三方库
如果不想手动实现,可以使用现成的 React 懒加载库,如 react-lazyload 或 react-lazy-load-image-component。
安装 react-lazyload:
npm install react-lazyload
使用示例:

import React from 'react';
import LazyLoad from 'react-lazyload';
const LazyImage = ({ src, alt }) => (
<LazyLoad height={200} offset={100}>
<img src={src} alt={alt} />
</LazyLoad>
);
export default LazyImage;
注意事项
- 占位符:懒加载时建议使用占位符(如低分辨率图片或纯色背景)以避免布局跳动。
- 性能优化:滚动事件监听需要节流或防抖,Intersection Observer 是更优选择。
- SEO:确保搜索引擎能抓取懒加载的图片,可以通过
noscript标签或服务器端渲染支持。
以上方法可根据项目需求和技术栈选择适合的实现方式。






