为了应用的性能,我们通常都会使用code splitting,当前大部分 React 应用都选择使用 react-loadable 来处理。然而,React 16.6添加了一个新的特性: React.lazy(), 它可以让代码分割(code splitting)更加容易。
基本使用
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
React.lazy()接收一个匿名函数作为参数,在函数中动态引入<OtherComponent />组件。这样在我们渲染这个组件前,浏览器将不会下载<OtherComponent />组件和它的依赖。
React.lazy()目前仅支持默认导出
Suspense
如果React要渲染<OtherComponent />组件时,组件依赖的代码还没下载好,我们需要展示一些提示内容,在等待组件加载的时候,这时我们就需要用到React.Suspense组件。
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<React.Suspense fallback={<Spinner />}>
<OtherComponent />
</React.Suspense>
);
}
React.Suspense接收任何类型的React元素,以便在我们等待异步加载时进行渲染。
在代码未下载好前,React.Suspense将会渲染fallback props属性传入的值,当全部子节点依赖的代码都准备好后,才会去渲染子节点内容。
加载出错的处理
如果其他模块无法加载(例如,由于网络故障),则会触发错误,可以使用Error Boundary处理这些错误以显示良好的用户体验。
import MyErrorBoundary from './MyErrorBoundary';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const MyComponent = () => (
<div>
<MyErrorBoundary>
<Suspense fallback={<Spinner />}>
<OtherComponent />
</Suspense>
</MyErrorBoundary>
</div>
);
与react-loadable对比
在react-loadable 当中,按需加载可能在长这样:
const Loading = ({ pastDelay }) => {
if (pastDelay) {
return <Spinner />;
}
return null;
};
export const LoadingComponent = Loadable({
loader: () => import('./OtherComponent'),
loading: Loading,
delay: 200
});
在上面的代码中,我们做了几个事情:
- 我们定义一个 Loading 组件,用于在请求组件的时间和加载组件以及准备渲染之间显示。
- LoadingComponent 中的loading参数是在请求/响应周期中显示的组件,这里我们定义了一个 自定义Loading组件
- 设置了一个delay,我们只在加载超过 200 毫秒的时候显示Spinner ,这样做可以很好地避免在请求快速完成时“闪烁”加载中的组件。
使用 React.Suspense 显然代码更为优雅。
const OtherComponent = React.lazy(() => import('./OtherComponent'));
export const MyComponent = props => (
<React.Suspense fallback={<Spinner />}>
<OtherComponent {...props} />
</React.Suspense>
);
到此,其实我们已经实现了和 react-loadable 一样的功能。仔细看我们会发现,React.Suspense 没有 delay 参数。目前React.Suspense 没有在内置支持delay 功能,如果资源被加载得非常快得话,加载动画可能会出现闪一下,为了避免这种情况,我们需要自己在 fallback 的组件中自行处理这些逻辑,例如在 componentDidMount 中设置一个定时器,使其直到将来的某个时间才呈现。
优点
去除了第三方的库,我们打包的体积可以变的更小。
使用
React的核心库,总比第三方库更容易维护。

