使用动态导入和交叉观察器延迟加载反应组件
延迟加载
延迟加载是一种仅在需要时加载内容的方法。这是通过代码拆分实现的,我们将应用拆分成多个代码块。这样做的目的是只向用户提供他们能够查看的内容,并在用户访问时提供其他内容。
基于路由的代码拆分
例如,假设我们有一个网站,其中包含/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,并带有一个ref
和inView
标志。ref
应该附加到目标元素上,并inView
让我们知道目标元素是否在视口中。选项是一个介于和threshold
之间的值,表示触发前元素可见的百分比。0
1
现在,<HeavyForm />
只有当它在视口中时才会下载。
结论
此技术可以扩展到多个路由和组件,轻松缩短页面初始加载时间。请记住在延迟加载的组件和添加到主 bundle 中的组件之间取得平衡。请求延迟加载的内容时,需要进行网络往返的代价。
谢谢!
您可以在此处查看完整的源代码
文章来源:https://dev.to/siddharthvenkatesh/lazy-loading-react-components-with-dynamic-imports-and-intersection-observer-24mh