关键步骤
- 创建延迟加载组件:将需要延迟加载的内容封装到一个单独的组件中。例如,假设要延迟加载一个图片展示组件,创建
LazyImage
组件。
- 使用
import()
语法:在主组件中,不直接导入延迟加载组件,而是使用动态 import()
。例如:
const LazyImage = () => {
const [ImageComponent, setImageComponent] = useState(null);
useEffect(() => {
import('./LazyImageComponent').then((module) => {
setImageComponent(module.default);
});
}, []);
return ImageComponent? <ImageComponent /> : null;
};
- 触发加载时机:上述代码中,在
useEffect
钩子中,当组件挂载时触发延迟加载。也可以根据其他条件,比如用户滚动到特定位置时触发加载。例如,结合 IntersectionObserver
API 实现滚动到可见区域时加载:
const LazyImage = () => {
const [ImageComponent, setImageComponent] = useState(null);
const ref = useRef(null);
useEffect(() => {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
import('./LazyImageComponent').then((module) => {
setImageComponent(module.default);
});
observer.unobserve(ref.current);
}
});
if (ref.current) {
observer.observe(ref.current);
}
return () => {
if (ref.current) {
observer.unobserve(ref.current);
}
};
}, []);
return (
<div ref={ref}>
{ImageComponent? <ImageComponent /> : null}
</div>
);
};
主要概念
- 动态导入 (
import()
):这是 ECMAScript 提供的一种异步导入模块的方式。它返回一个 Promise
,允许在运行时动态加载代码,而不是在编译时就将所有代码都包含进来。这对于延迟加载组件非常有用,因为可以按需加载组件,减少初始加载的代码量。
- 状态管理 (
useState
):在上述示例中,useState
用于存储延迟加载组件是否已经加载完成的状态。null
表示未加载,加载完成后存储实际的组件。
- 副作用钩子 (
useEffect
):useEffect
用于在组件挂载、更新或卸载时执行副作用操作。在这里,我们使用它来触发延迟加载的操作,确保在合适的时机加载组件。
- IntersectionObserver API:用于异步观察目标元素与其祖先元素或顶级文档视口的交集变化情况。在延迟加载组件场景中,可用来判断组件是否进入视口,从而决定是否触发加载,优化用户体验,避免过早加载不可见的组件。