react4.0 按需加载_在React 16.6中延迟加载(和预加载)组件

react4.0 按需加载

React 16.6增加了一个新功能,使代码拆分更加容易: React.lazy()

让我们看看如何以及为什么在一个小型演示中使用此功能。

我们有一个显示股票清单的应用程序。 当您单击一只股票时,它将显示一个图表:

试试吧

这就是全部。 您可以在github存储库中阅读完整的代码(也可以查看pull请求以查看差异以及我们将要执行的每个更改的应用程序运行版本)。

对于这篇文章,我们只关心App.js文件中的内容:

我们有一个App组件,该组件接收股票列表并显示<StockTable/> 。 从表中选择股票后, App组件将显示该股票的<StockChart/>

有什么问题? 好吧,我们希望我们的应用程序能够快速发展并尽可能快地显示<StockTable/> ,但是我们正在等待它下载直到浏览器下载(并解压缩,解析,编译和运行) <StockChart/>的代码。

让我们看一下显示<StockTable/>需要多长时间:

跟踪而无需延迟加载

显示StockTable(带有模拟的Fast 3G网络和4x减速CPU)需要2470 ms。

我们运送到浏览器的125KB(压缩文件)中有什么?

Webpack捆绑分析器报告

不出所料,我们有React,React主导和一些React依赖性。 但是我们也有时刻,lodash和胜利,我们只需要<StockChart/> ,而不需要<StockTable/>

为了避免<StockChart/>依赖关系减慢<StockTable/>的加载速度,我们该怎么做? 我们延迟加载组件。

延迟加载组件

使用动态导入,我们可以将绑定的javascript分成两部分,一个是仅包含显示<StockTable/>所需代码的主文件,另一个是包含代码和<StockChart/>所需的依赖项的文件。

这项技术是如此有用,以至于React 16.6添加了一个API,以使其更易于与React组件一起使用: React.lazy()

为了使用React.lazy()在我们的App.js我们做出两个改变:

差异

首先,我们将静态导入替换为对React.lazy()的调用, React.lazy()其传递返回动态导入的函数。 现在,浏览器将不会下载./StockChart.js (及其依赖项),直到我们首次呈现它。

但是,当React想要渲染<StockChart/>而又没有代码时会发生什么呢? 这就是我们添加<React.Suspense/> 。 它将加载fallback道具而不是其子项,直到加载了所有子项的所有代码为止。

现在,我们的应用程序将捆绑在两个文件中:

Webpack捆绑分析器报告

js主文件为36KB。 另一个文件为89KB,具有./StockChart的代码及其所有依赖项。

让我们再次看看浏览器显示这些更改后<StockTable/>

延迟加载跟踪

浏览器需要760毫秒(而不是1250毫秒)来下载主要js文件,而花费61毫秒(而不是487毫秒)来评估脚本。 <StockTable/>在1546毫秒(而不是2470毫秒)中显示。

预加载惰性组件

我们使我们的应用程序加载速度更快。 但是现在我们还有另一个问题:

在显示图表之前请注意“正在加载...”( 尝试一下

用户第一次单击项目时,将显示“正在加载...”后备广告。 那是因为我们需要等到浏览器加载<StockChart/>的代码。

如果要摆脱“正在加载...”后备广告,我们将必须在用户单击股票之前加载代码。

预加载代码的一种简单方法是在调用React.lazy()之前启动动态导入:

当我们调用动态导入时,该组件将开始加载,而不会阻止<StockTable/>的呈现。

看一下跟踪如何从原始的eager-loading应用程序更改:

渴望加载与延迟加载

现在,如果用户在显示表格后不到1秒的时间内单击库存,则只会看到“正在加载...”后备广告。 试试吧

您还可以增强lazy功能,以便在需要时更轻松地预加载组件:

预渲染组件

对于我们的小型演示应用程序,这就是我们所需要的。 对于更大的应用程序,惰性组件可能需要加载其他惰性代码或数据才能呈现。 因此,用户仍然必须等待这些。

预加载组件的另一种方法是在需要它之前实际渲染它。 我们想要渲染它,但我们不想展示它,所以我们将其渲染为隐藏的:

在第一次渲染应用程序时,React将开始加载<StockChart/> ,但这一次它实际上将尝试呈现<StockChart/>因此,如果需要加载任何其他依赖项(代码或数据),它将被加载。

我们将惰性组件包装在一个hidden div因此在加载后它不会显示任何内容。 然后,我们将该div封装在另一个<React.Suspense/>并使用null后备,因此在加载时它不会显示任何内容。

注意: hiddenHTML属性,用于指示该元素尚不相关。 浏览器不会渲染具有此属性的元素。 React对那个属性没​​有做任何特别的事情(但是它可能会在以后的版本中开始给隐藏的元素一个较低的优先级)。
少了什么东西?

后一种方法在许多情况下很有用,但存在一些问题。

首先,用于隐藏渲染的惰性组件的hidden属性不是防弹的。 例如,惰性组件可以使用不会被隐藏的门户有一种hack不需要额外的div,并且也可以与portal一起使用,但这是一种hack,它会崩溃)。

其次,即使隐藏了组件,我们仍将未使用的节点添加到DOM中,这可能会成为性能问题。

更好的办法是告诉React以呈现惰性组件,但在加载后不将其提交到DOM。 但是,据我所知,当前版本的React无法实现。

我们可以做的另一个改进是在预加载图表组件时重用我们渲染的元素,因此当我们想要实际显示图表时,React不需要再次创建它们。 如果我们知道用户将点击什么库存,我们甚至可以在用户单击它之前用正确的数据渲染它( 像这样 )。

就这样。 谢谢阅读。

更多类似的内容,请 在Twitter上 关注 @pomber

翻译自: https://hackernoon.com/lazy-loading-and-preloading-components-in-react-16-6-804de091c82d

react4.0 按需加载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值