您永远不需要向用户分发超出必要的代码,因此请对软件包进行拆分,以确保这种情况永远不会发生!
使用 React.lazy
方法可轻松对 React 应用进行代码拆分,
动态导入。
import React, { lazy } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const DetailsComponent = () => (
<div>
<AvatarComponent />
</div>
)
为什么搜索渠道报告非常实用?
大型 React 应用通常由许多组件、实用程序 方法和第三方库。如果没有尝试加载 一个大型应用的不同部分 在用户加载 首页。这可能会严重影响网页性能。
React.lazy
函数提供了一种内置方式来分隔
将应用拆分成单独的 JavaScript 块,几乎不用费力。您可以
然后在与 Suspense
结合使用时处理加载状态
组件。
悬疑
向用户传送大量 JavaScript 有效负载的问题在于, 网页完成加载所需的时间,尤其是在性能较低的设备上 和网络连接正因如此,代码拆分和延迟加载才 非常有用。
不过,在加载和编辑内容时,
代码拆分组件是通过网络提取的,因此请务必
显示有用的加载状态。将 React.lazy
与 Suspense
搭配使用
有助于解决此问题。
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
</Suspense>
)
Suspense
接受 fallback
组件,可让您显示任何 React
组件加载为加载状态以下示例展示了具体工作原理。
仅在用户点击按钮时呈现头像,其中请求是
然后用于检索已暂停的 AvatarComponent
所需的代码。
同时,系统会显示后备加载组件。
在这里,构成 AvatarComponent
的代码很小,
说明加载旋转图标为何仅显示一小段时间。更大
组件可能需要更长时间才能加载完毕
网络连接信号较弱
为了更好地演示此操作的工作原理:
- 如需预览网站,请按查看应用。然后按
全屏
。
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
- 点击网络标签页。
- 点击限制下拉菜单,其默认设置为无限制。选择 Fast 3G。
- 点击应用中的 Click Me 按钮。
加载指示器现在会显示更长时间。请注意
构成了 AvatarComponent
作为单独的分块进行提取。
![显示正在下载一个 chunk.js 文件的开发者工具网络面板](https://web.developers.google.cn/static/articles/code-splitting-suspense/image/devtools-network-panel-sh-bab60da5120ad.png?authuser=9&hl=ro)
挂起多个组件
Suspense
的另一个功能是
即使所有组件均采用延迟加载方式,也是如此。
例如:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
const DetailsComponent = () => (
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
)
这是一种非常有用的方式,可延迟多个组件的渲染, 仅显示一种加载状态所有组件都完成后 提取后,用户可以同时看到所有内容。
通过下面的嵌入代码,您可以看到此代码:
否则,就很容易遇到交错加载问题,或者 界面的不同部分接连加载,并且每个部分都有自己的 “正在加载”指示器这可能会使用户体验显得更加不协调。
处理加载失败问题
借助 Suspense
,您可以在连接到网络时显示临时加载状态
请求都是在后台进行的但如果这些网络请求失败了,该怎么办?
为什么?您可能处于离线状态,也可能是因为您的 Web 应用正在尝试
延迟加载带版本号的网址
过期且在服务器重新部署后不再可用。
React 具有标准模式,可以妥善处理这些类型的加载
失败:使用错误边界。如文档中所述,
如果任何 React 组件实现以下任一项(或
static getDerivedStateFromError()
或
componentDidCatch()
。
如需检测和处理延迟加载故障,您可以封装 Suspense
组件与充当错误边界的父组件相关联。在
错误边界的 render()
方法,则可以按原样渲染子项,如果存在
没有错误,或者在出现问题时显示自定义错误消息:
import React, { lazy, Suspense } from 'react';
const AvatarComponent = lazy(() => import('./AvatarComponent'));
const InfoComponent = lazy(() => import('./InfoComponent'));
const MoreInfoComponent = lazy(() => import('./MoreInfoComponent'));
const renderLoader = () => <p>Loading</p>;
class ErrorBoundary extends React.Component {
constructor(props) {
super(props);
this.state = {hasError: false};
}
static getDerivedStateFromError(error) {
return {hasError: true};
}
render() {
if (this.state.hasError) {
return <p>Loading failed! Please reload.</p>;
}
return this.props.children;
}
}
const DetailsComponent = () => (
<ErrorBoundary>
<Suspense fallback={renderLoader()}>
<AvatarComponent />
<InfoComponent />
<MoreInfoComponent />
</Suspense>
</ErrorBoundary>
)
总结
如果您不确定从何处开始将代码拆分应用于 React 请按以下步骤操作:
- 从路线级别开始。路线是标识某地点的点的最简单方法
以及可拆分的应用通过
React 文档
展示了如何将
Suspense
与react-router
。 - 找出您网站上的网页上是否存在仅在 某些用户互动(例如点击某个按钮)。拆分这些内容 最大程度地减少 JavaScript 载荷。
- 考虑拆分屏幕外的其他内容, 用户。