The Complete Junior to Senior Web Developer Roadmap - Performance part2 隨意筆記
前言
這章節主要在講述 React Performance 的優化。
為何要 code splitting
如果不做 code splitting,就會直接載入 Webpack bundle 好的一大包檔案,這當然也是沒問題,但使用者就會因為下載這一大包檔案而在使用時卡住一陣子,影響使用者體驗。
code splitting 的用意就是在進入那個頁面,需要使用那個 Component 時才下載檔案,改善網頁讀取速度,增進使用體驗。
Code Splitting - React lazy
[译] 延迟加载 React Components (用 react.lazy 和 suspense)
React 官方提供 code splitting 的方法是 React.lazy
,以下提供簡單的使用範例,可以到 這裡 clone 專案玩玩看
這邊課程提供的是一個自製的 router,在點擊按鈕的同時,就會切換到不同 route,return 相對應的 component,達到 code splitting 的效果。
首先要用 React.lazy 包裹著要 import 進來的檔案。
const Page2Lazy = React.lazy(() => import('./Components/Page2'))
const Page3Lazy = React.lazy(() => import('./Components/Page3'))
再來在相對應的 return Component 中,加入 Suspense 包裹住使用 React.lazy 的 Component。
render() {
if (this.state.route === 'page1') {
return <Page1 onRouteChange={this.onRouteChange} />
} else if (this.state.route === 'page2') {
return (
<Suspense fallback={<div>Loading...</div>}>
<Page2Lazy onRouteChange={this.onRouteChange} />
</Suspense>
)
} else {
return (
<Suspense fallback={<div>Loading...</div>}>
<Page3Lazy onRouteChange={this.onRouteChange} />
</Suspense>
)
}
}
lazy component 都必須包裹在 Suspense Component 裡面,Suspense 的用處在於可以在 fallback 這個 props 放入 loading 時要給予的 Component,以避免在 import 檔案時的空檔使用者會很疑惑,陷入等待空畫面的狀態。
當然,搭配 Router 也是可以的,就像下面這樣:
render() {
return(
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/page1" component={Page1}/>
<Route path="/page2" component={Page2Lazy}/>
<Route path="/page2" component={Page3Lazy}/>
</Switch>
</Suspense>
)
}
另外,關於 module 載入失敗的 error 也可以做相對應的處理,可以寫一個 ErrorBoundary 的 Component 來處理錯誤,更多詳情在 React 官方文件 - 錯誤邊界 可以參考。
使用的話就像這樣:
const MyComponent = () => (
<div>
<MyErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</MyErrorBoundary>
</div>
);
SSR
值得注意的是,React.lazy 並不能用在 Server Side Rendering,所以如果要做 SSR 的話,可以改用另一個叫做 Loadable Components 的套件!
另外當然還有其他優化能做,比如 class component 裡的 shouldComponentUpdate,React Hooks 裡面的 useCallback 等等,課程裡面也有提及,但目前有點懶惰,先紀錄下 React lazy~