在React16.6中引入了React.lazy和React.Suspense,這兩個(gè)組件蒿囤,可以用來實(shí)現(xiàn)異步加載組件客们。
它們在React 16.6之前是如何實(shí)現(xiàn)的?
對于懶加載React組件最流行的庫可能是react-loadable
對比react-loadable材诽,React.Suspense還是有一些不足底挫。
- 加載組件缺少delay參數(shù),不能解決請求快速完成時(shí)的"閃爍"問題(即使加載模塊只需要幾毫秒的時(shí)間脸侥, fallback也會被執(zhí)行建邓,就上述代碼來說,也就是 Spinner 會閃爍一下)湿痢,需要自己封裝
- 沒有內(nèi)置的加載錯(cuò)誤處理方法涝缝,需要自己去處理
- react-loadable有預(yù)加載支持,React.Lazy沒有
React.lazy 用于做Code-Splitting譬重,代碼拆分。類似于按需加載罐氨,渲染的時(shí)候才加載代碼臀规。
import React, {lazy} from 'react';
const OtherComponent = lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<OtherComponent />
</div>
);
}
lazy(() => import('./OtherComponent'))使用es6的import()返回一個(gè)promise,類似于:
lazy(() => new Promise(resolve =>
setTimeout(() =>
resolve(
// 模擬ES Module
{
// 模擬export default
default: function render() {
return <div>Other Component</div>
}
}
),
3000
)
));
React.lazy的提出是一種更優(yōu)雅的條件渲染解決方案栅隐。
之所以說他更優(yōu)雅塔嬉,是因?yàn)樗麑l件渲染的優(yōu)化提升到了框架層。
這里我們引出suspense租悄。
當(dāng)我們組件未渲染完成谨究,需要loading時(shí),可以這么寫:
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
在我們的業(yè)務(wù)場景中泣棋,OtherComponent可以代表多個(gè)條件渲染組件胶哲,我們?nèi)考虞d完成才取消loding。
只要promise沒執(zhí)行到resolve潭辈,suspense都會返回fallback中的loading鸯屿。
代碼簡潔,loading可提升至祖先組件把敢,易聚合寄摆。相當(dāng)優(yōu)雅的解決了條件渲染。