引言
當前大部分 React 應用需要使用
code splitting
的時候,都選擇使用優秀的 react-loadable 來處理檢測代碼段是否已加載。愛掏網 - it200.com然而,隨著React v16.6 的發布,我們有一個非常難得的機會 ,可以刪除我們的第三方依賴!
React.Suspense是一個新添加到核心React庫中的功能,t他的功能基本和 react-loadable 一致,所以不用多說,讓我們來看看用 React.Suspense
替換 react-loadable
。愛掏網 - it200.com
首先是 code splitting(代碼分割)
如果你不太熟悉這個功能,webpack 基本上可以幫助你把代碼打包成多個chunk,當用戶打開你的應用的時候,先會下載一個主bundle,然后當用戶導航到一些頁面包含了其他的邏輯和靜態資源的使用,再按需加載這些chunk。愛掏網 - it200.com但是要手動處理成這個效果非常的復雜,當然這樣處理后可以很有效地減少用戶的白屏時間,并且讓移動端用戶有更好的體驗。愛掏網 - it200.comwebpack(或者其他解決方案)在這里扮演了一個很重要的角色,他可以在創建這些bundle的時候處理這些復雜的邏輯,并且在需要的時候再去下載他們。愛掏網 - it200.com所以我們所需要做的就是將該功能合并到我們的應用程序中,這樣用戶就可以獲得無縫的體驗。愛掏網 - it200.com
Step 1: 升級到 React 16.6
對于 v16 的用戶來說,可以直接升級到 16.6,但是對于v15的用戶來說,請按照官方遷移說明來升級。愛掏網 - it200.com
Step 2: 確定您的異步組件
在 react-loadable 當中,按需加載可能在長這樣:
const Loading = ({ pastDelay }) => { if (pastDelay) { return; } return null; }; export const johanAsyncComponent = Loadable({ loader: () => import(/* webpackChunkName: "johanComponent" */ './johan.component'), loading: Loading, delay: 200 });
在上面的代碼中,我們做了幾個事情:
- 我們定義一個 Loading 組件,用于在請求組件的時間和加載組件以及準備渲染之間顯示。愛掏網 - it200.com
-
johanAsyncComponent
中的loading
參數是在請求/響應周期中顯示的組件,這里我們定義了一個 自定義Loading組件 - 設置了一個delay,我們只在加載超過 200 毫秒的時候顯示Spinner ,這樣做可以很好地避免在請求快速完成時“閃爍”加載中的組件。愛掏網 - it200.com
Step 3:轉換到 React.Suspense
使用 React.Suspense
顯然代碼更為優雅。愛掏網 - it200.com
const johanComponent = React.lazy(() => import(/* webpackChunkName: "johanComponent" */ './myAwesome.component')); export const johanAsyncComponent = props => (}> );
- 我們使用React.lazy封裝動態import,類似于第一個示例中的'loading'參數。愛掏網 - it200.com
- 我們定義一個
React.Suspense
組件,其中包含一組fallback
JSX,以便在我們等待異步加載時進行渲染。愛掏網 - it200.com 通常,這將是一個微調器或其他等待指示器。愛掏網 - it200.com - 我們定義了一些 children 的 JSX,這些都是使用 React.lazy 包含的組件。愛掏網 - it200.com
ok, 到此,其實我們已經實現了和 react-loadable 一樣的功能。愛掏網 - it200.com或許細心的你可能發現了,React.Suspense
沒有 delay 參數。愛掏網 - it200.com是的, React.Suspense
沒有在內置支持 delay 功能,因此,即使加載工程只需要幾毫秒的時間, fallback也會被執行,就上述代碼來說,也就是 Spinner 會閃爍一下,如果資源被加載得非常快得話。愛掏網 - it200.com就目前而言,我們需要自己在 fallback
得組件中自行處理這些邏輯,例如在 componentDidMount
中設置一個定時器,使其直到將來的某個時間才呈現。愛掏網 - it200.com
Step 4:加載出錯的處理
該如何處理如果出現chunk加載失敗的情況呢?
react-loadable
優秀的庫當然有內置的方法支持處理加載失敗的情況
const Loading = (props) => { if (props.error) { returnError!
; } else if (props.pastDelay) { returnLoading...
; } else { return null; } }
Suspense
在 React 16 當中有一個新的功能Error Boundary,這只是一個可感知錯誤的組件,它能夠從其children中捕獲和處理錯誤。愛掏網 - it200.com為了處理異步加載的問題,我們可以簡單地定義一個自定義的ErrorEdge組件,并將異步組件的使用包裝在其中。愛掏網 - it200.com
最后一步
npm uninstall react-loadable
替換有什么好處?
顯然,當我們考慮升級或重構時,我們總是用“它以目前的方式工作得很好”為借口推脫。愛掏網 - it200.com那么,這是否值得升級?
更小的bundle: react-loadable gzip后大概是 2K,去掉這個第三方庫后,所以打包時間并沒有減少多少,但是確確實實減少了2K。愛掏網 - it200.com
增加可維護性:使用 React 的核心庫,總比第三方庫更容易維護。愛掏網 - it200.com
總結
總的來說,我不敢說這是一個必須替換的功能,但是考慮到眾多的因素,他們兩個的功能基本是相同的,而且代碼修改也相對比較簡單,并不需要做很大的改動,所以建議使用這個新特性來做按需加載。愛掏網 - it200.com
原文鏈接:https://objectpartners.com/2024/12/05/migrate-from-react-loadable-to-react-suspense/
原文作者:Mike Plummer譯文地址:https://cloud.tencent.com/developer/article/1381296
譯文作者:志航