📜  React.lazy 和 @loadable/components 之间有什么区别?

📅  最后修改于: 2022-05-13 01:56:17.673000             🧑  作者: Mango

React.lazy 和 @loadable/components 之间有什么区别?

在讨论React.lazy@loadable/components之间的区别之前,让我们先谈谈它们是什么以及我们为什么需要它们。 React.lazy 和 @loadable/components 都主要用于Code-Splitting的过程。

代码拆分: Code-Splitting 是一种由 Webpack、Rollup 和 Browserify 等打包工具支持的优化技术(通过 factor-bundle),它允许我们将代码拆分成多个包或块,这些包或块可以在运行时按需或并行动态加载。

这是减少应用程序包大小的有效方法,因为我们只是“延迟加载”用户当前需要的东西。

尽管我们没有以这种方式减少应用程序中的代码总量,但我们避免了加载用户可能永远不需要的代码。这反过来又减少了初始加载期间所需的代码量,并显着改善了应用程序的整体加载时间。

React 实现 Code-Splitting: React 从 16.6.0 版本开始支持使用React.lazy开箱即用的代码拆分。

从那时起,在 React 应用程序中拆分我们的组件一直是一种常见的做法。然而仅仅拆分是不够的,它必须能够等待组件被加载(同时在加载过程中显示一个后备 UI)并处理任何潜在的错误。

这就是为什么我们需要使用SuspenseError Boundaries的原因。

Javascript
import React, { Suspense } from 'react';
import MyErrorBoundary from './MyErrorBoundary';
  
const SomeComponent = React.lazy(() => import('./SomeComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
  
const MyComponent = () => (
    
                     Loading...
}>                 
                                                          
                          
);


Javascript
import loadable from '@loadable/component'
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        
                     
    ) }


Javascript
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        
            Loading...
} />         
    ) }


Javascript
import loadable from '@loadable/component'
const Moment = loadable.lib(() => import('moment'))
function FromNow({ date }) {
    return (
        
                             {({ default: moment }) =>                      moment(date).fromNow()}                      
    ) }


Javascript
import loadable from '@loadable/component'
const AsyncPage = loadable(props => 
    import(`./${props.page}`))
function MyComponent() {
  return (
    
                  
  ) }


正如我们从上面的示例中看到的,React.lazy 接受一个调用动态 import() 的函数并返回一个 Promise,该 Promise 解析为具有包含 React 组件的默认导出的模块。然后惰性组件在Suspense组件中呈现,这允许我们在等待惰性组件加载时显示一些备用内容(例如加载指示器)。错误边界还用于处理可能由于网络问题或类似原因而导致的任何错误。

@loadable/component:虽然 React.lazy 和 Suspense 是代码拆分的推荐解决方案,但它有一些限制。 React.lazy 和 Suspense 还不能用于服务器端渲染。因此,如果您想在服务器渲染的应用程序中进行代码拆分,那就是@loadable/component发挥作用的时候。

Javascript

import loadable from '@loadable/component'
const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        
                     
    ) }

那么它们之间有哪些主要区别呢?

 SSRSuspenseLibrary splittingFull dynamic import
React.lazy
@loadbale/component

SSR: @loadable/component 提供了使服务器端渲染成为可能的完整解决方案,而 React.lazy 在服务器端渲染方面不是一个选项。因为 Suspense 在 Server-Side 中不可用,而 React.lazy 只能与 Suspense 一起使用。

Suspense:虽然 @loadable/component 和 React.lazy 都支持 Suspense,但它们之间的区别是 @loadable/component 也可以在没有 Suspense 的情况下使用。

Javascript

const OtherComponent = loadable(() => import('./OtherComponent'))
function MyComponent() {
    return (
        
            Loading...
} />         
    ) }

库拆分: @loadable/component 支持使用渲染道具进行库拆分,这在 React.lazy 中是不可能的。

Javascript

import loadable from '@loadable/component'
const Moment = loadable.lib(() => import('moment'))
function FromNow({ date }) {
    return (
        
                             {({ default: moment }) =>                      moment(date).fromNow()}                      
    ) }

全动态导入: Webpack 支持全动态导入或激进的代码拆分。您可以通过将动态值传递给动态 import()函数来使用它们来创建可重用的可加载组件。

Javascript

import loadable from '@loadable/component'
const AsyncPage = loadable(props => 
    import(`./${props.page}`))
function MyComponent() {
  return (
    
                  
  ) }