使用动态导入和交叉观察器延迟加载反应组件

2025-05-26

使用动态导入和交叉观察器延迟加载反应组件

延迟加载

延迟加载是一种仅在需要时加载内容的方法。这是通过代码拆分实现的,我们将应用拆分成多个代码块。这样做的目的是只向用户提供他们能够查看的内容,并在用户访问时提供其他内容。

基于路由的代码拆分

例如,假设我们有一个网站,其中包含/home/profile/about路由,并且/home是用户首次访问的页面。如果我们可以将这三个路由编译成三个 bundle,那么我们就可以在用户访问相应页面时提供它们。home路由的代码将仅包含组件中的代码<Home />。当用户访问 时/about,该路由的内容将被下载并显示。如果我们的应用程序规模较大且包含大量路由,这将显著提升初始页面加载速度。

基于组件的代码拆分

上面的例子描述了什么是基于路由的代码拆分策略。我们可以更进一步,使用基于组件的代码拆分策略。假设我们有一个很重的表单组件,它深藏在应用中,用户很少会用到。那么将它添加到主 bundle 中就毫无意义了,而且这恰恰是延迟加载的完美方案。

动态导入

我们可以在 React 中使用动态导入来实现这一点。React 为我们提供了利用动态导入的方法,React.lazy详情请Suspense 参阅 React 文档

让我们构建一个示例。我们有一个虚拟的表单组件<HeavyForm />。它什么也不做,但你明白我的意思了。
图像

如果我们想动态导入它,我们可以这样做
图像

路口观察员

如果你现在运行代码,你会看到它HeavyForm被下载为一个单独的 js 文件。这意味着它HeavyForm被打包为一个单独的 chunk,并且它不是我们主 bundle 的一部分。

太棒了!不过,它还是会在页面加载后立即下载。我们希望它只在页面可见时下载,也就是用户真正看到它的时候。

这时IntersectionObserver就派上用场了。IntersectionObserver 会让我们了解目标元素是否在视口中。我们可以放心地假设,如果 IntersectionObserver 触发,则目标元素就在视口中。我们可以利用这一点,在组件位于视口中时对其进行惰性加载。

我将使用react-intersection-observer库,它底层使用原生 IntersectionObserver,并为我们提供了易于使用的简洁钩子。

图像

这就是使用 IntersectionObserver 的完整实现。react-intersection-observer它提供了useInView一个 hook,并带有一个refinView标志。ref应该附加到目标元素上,并inView让我们知道目标元素是否在视口中。选项是一个介于threshold之间的值,表示触发前元素可见的百分比。01

现在,<HeavyForm />只有当它在视口中时才会下载。

结论

此技术可以扩展到多个路由和组件,轻松缩短页面初始加载时间。请记住在延迟加载的组件和添加到主 bundle 中的组件之间取得平衡。请求延迟加载的内容时,需要进行网络往返的代价。
谢谢!

您可以在此处查看完整的源代码

文章来源:https://dev.to/siddharthvenkatesh/lazy-loading-react-components-with-dynamic-imports-and-intersection-observer-24mh
PREV
React 渲染的视觉指南 - 速查表
NEXT
什么是虚拟 DOM?(让我们来构建它!)