使用React的懒惰加载指南

85 阅读5分钟

简介

在开发大型React应用时,我们通常会使用许多图片和视频,安装第三方包/库,进行API调用,以及做其他各种事情。这自然会增加加载我们的应用程序的时间,并导致大量的包的大小,从而导致用户体验不佳。这就是懒人加载的作用。它使我们能够及时加载内容,就在它将被显示在应用程序中之前。

我们可以避免在内容还在视图之外的时候就预先加载,并将所有的资源集中在视图中的内容上。

在本指南中,我们将了解如何使用React.lazy()React.Suspense 来实现懒惰加载和代码分割功能,这使得我们无需安装任何额外的库就能处理代码分割。

什么是懒惰加载?

当我们启动一个React网络应用程序时,它通常会一次性捆绑整个应用程序,为我们加载包括整个网络应用程序页面、图片、内容等在内的所有内容,可能会导致加载时间缓慢,整体性能不佳,这取决于内容的大小和当时的互联网带宽。

懒惰加载允许我们只在需要时加载特定的组件。通常情况下,我们也会将代码分割成逻辑组件,这些组件也可以与内容一起被懒惰加载。

例如,如果我们有一个仪表盘页面,点击后会显示很多来自不同来源的信息,那么最好让这些组件和页面保持懒惰加载,这样它们只有在用户需要或需要时才会加载。

**注意:**将一个大的代码包吐成多个可以动态加载的代码包,其总体目标是避免与过大的代码包相关的性能问题,这个过程被称为代码拆分。这是在不减少我们应用程序中的代码量的情况下实现的。

总之,懒惰加载允许我们按需渲染组件或元素,使我们的应用程序更有效率,并提供更好的用户体验。

**注意:*单页应用程序(SPA)*被设计为在单个文档/页面中包含所有页面和内容。这就是为什么懒惰加载在开发SPA时特别方便的原因。

如何在React中实现懒惰加载

到目前为止,我们已经看到了什么是懒惰加载,以及为什么它的实现很重要。现在,让我们看看如何在我们的React应用程序中实现它,使用两个React功能,使代码分割和懒惰加载容易实现 -React.lazy()React.Suspense

React.lazy() 是一个允许我们以与普通组件相同的方式渲染动态导入的函数。在 旁边使用动态导入将使我们能够在一个组件在屏幕上呈现之前导入它。需要注意的是, 接受一个函数作为参数--该函数必须在其主体中调用动态 。React.lazy() React.lazy() import()

React.Suspense 这使我们能够指定回退道具,该道具接收一个占位符内容,在所有懒惰组件被加载时作为加载指示器使用。

让我们开始看看我们如何在导入的组件中实现懒惰加载,然后我们如何在我们的路由中实现它,以便页面在我们导航到它们之前不被加载。

开始吧

假设我们有我们的React应用程序,并且我们将About 组件导入到Home

import AboutUs from './About';

const Home = () => {
   return (
      <div className="App">
         <h1>Home Page</h1>
         <AboutUs />
      </div>
   );
};

export default Home;

我们现在可以通过利用React.lazy() 来实现懒惰加载。

import React from 'react';

// Lazy loading 
const AboutUs = React.lazy(() => import('./About'));

const Home = () => {
   return (
      <div className="App">
         <h1>Home Page</h1>
         <AboutUs />
      </div>
   );
};
export default Home;

**注意:**这样使用的React.lazy() 会返回一个Promise 对象。该承诺解析到一个模块,该模块包含我们想在其default 输出中懒惰加载的React组件。

我们已经使用React.lazy() 实现了懒惰加载,但上面的代码总是抛出一个错误,说我们的“React component suspended while rendering, but no fallback UI was specified” 。这可以通过用React.Suspense'sfallbackz 包装该组件并附加我们前面解释的回退道具来解决。

import React from 'react';
const AboutUs = React.lazy(() => import('./About'));

const Home = () => {
   return (
      <div className="App">
         <h1>Home Page</h1>
         <React.Suspense fallback={<div>Loading...</div>}>
            <AboutUs />
         </React.Suspense>
      </div>
   );
};
export default Home;

**注意:**回退道具可以在原始内容加载之前将一个组件显示出来。

此外,我们可以决定取消React导入的结构,使代码更简洁,更易读。

import { lazy, Suspense } from 'react';
const AboutUs = lazy(() => import('./About'));

const Home = () => {
   return (
      <div className="App">
         <h1>Home Page</h1>
         <Suspense fallback={<div>Loading...</div>}>
            <AboutUs />
         </Suspense>
      </div>
   );
};
export default Home;

到目前为止,我们已经看到了如何在我们导入的组件中实现懒惰加载。现在,让我们看看如何在我们的路由中实现它,同时用React路由器进行路由。

如何用React Router实现懒惰加载

懒惰路由实际上是一个很好的做法,因为路由有很多内容,可能会减慢你的应用程序的加载时间。实现React路由的懒惰加载与我们之前在懒惰加载动态导入的组件时的做法几乎相同。

懒惰加载React路由是指只有在需要的时候才动态导入一个组件。例如,假设我们的应用程序中有两个路由和两个代表这些路由的组件。如果我们以如下方式实现提到的路由,每个组件只有在我们导航到相应的路由时才会被加载。

import { lazy, Suspense } from 'react';
import { BrowserRouter, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./Home'));
const Products = lazy(() => import('./Products'));

function App() {
   return (
      <BrowserRouter>
         <Suspense fallback={<div>Loading...</div>}>
            <Routes>
               <Route path="/" element={<Home />} />
               <Route path="/products" element={<Products />} />
            </Routes>
         </Suspense>
      </BrowserRouter>
   );
}
export default App;

结论

在本指南中,我们了解了什么是懒惰加载和代码分割,如何实现它们,以及实现懒惰加载的最佳位置是路由。这可以避免一次性渲染整个页面,在处理有大量内容的页面时,这可能会导致加载时间变慢。