代碼分割(Code Splitting)

代碼分割(Code Splitting)

來自專欄 前端譯欄Code-Splitting - React?

reactjs.org圖標

一 打包

React應用流行用類似Webpack和Browserify打包(bundled)。打包就是把導入的多個文件合併到一個文件的過程: 這個bundle就可以被引入到一個網頁進行載入。

例子

  • 原始代碼

//app.jsimport { add } from ./math.js;console.log(add(16, 26));//math.jsexport function add(a,b){ return a+b;}

  • 打包之後:

function add(a,b){ return a+b;}console.log(add(16, 26));

二 代碼分割

隨著應用擴展,包(bunle)會越來越大。尤其是如果引入了龐大的第三方庫。你必須留意你引入的包的大小。防止你打包之後,app載入需要太長時間。

為了防止弄出來一個大包,代碼分割是一個比較好的解決辦法。代碼分割是Webpack和Browserify(通過factor-bundle)的一個特性。允許創建多個包,然後在運行時(runtime)載入。

代碼分割可以幫助App實現『懶載入』當前用戶需要的那一部分,而不必全部載入。這樣動態載入能提高應用性能表現。

使用 import()語法

引入代碼分割的最好方式是使用動態import語法。

import { add } from ./math;console.log(add(16,26));

使用動態import()語法之後

import("./math").then(math=>{ console.log(math.add(16, 26));})

  • 注意: 動態import()語法是ECMAScript提案,不是標準。

當Webpack遇到這個語法,它就會自動切割你的app.如果你使用CreateReactApp腳手架,可以立即使用.

如果你自己使用Webpack來配置,那麼你的Webpack配置大致應該像這樣

如果用Babel,你要確保Babel可以解析動態import語法而不是轉譯這個語法。這需要用 babel-plugin-syntax-dynamic-import。

使用庫實現代碼分割

React Loadable用一種React方式友好地封裝了動態import語法

  • 使用之前

import OtherComponent from .OtherComponent;const MyComponent = () =>( <OtherComponent/>)

  • 使用React Loadable之後

import Loadable from react-loadable;const LoadableOtherComponent = Loadable({ loader: ()=> import(./OtherComponent), loading:()=> <div>Loading...</div>})const MyComponent = () => ( <LoadableOtherComponent/>)

React Loadable幫助你創建很多,比如:

1.狀態載入

function Loading() { return <div>Loading...</div>;}Loadable({ loader: () => import(./WillFailToLoad), // oh no! loading: Loading,});

2.錯誤狀態

function Loading(props) { if (props.error) { return <div>Error! <button onClick={ props.retry }>Retry</button></div>; } else { return <div>Loading...</div>; }}

3.超時提示

function Loading(props) { if (props.error) { return <div>Error! <button onClick={ props.retry }>Retry</button></div>; } else if (props.timedOut) { return <div>Taking a long time... <button onClick={ props.retry }>Retry</button></div>; } else if (props.pastDelay) { return <div>Loading...</div>; } else { return null; }}

4.預載入

const LoadableBar = Loadable({ loader: () => import(./Bar), loading: Loading,});class MyComponent extends React.Component { state = { showBar: false }; onClick = () => { this.setState({ showBar: true }); }; onMouseOver = () => { LoadableBar.preload(); }; render() { return ( <div> <button onClick={this.onClick} onMouseOver={this.onMouseOver}> Show Bar </button> {this.state.showBar && <LoadableBar/>} </div> ) }}

5.服務端渲染

以路由為基礎代碼分割

在什麼地方決定使用代碼分割是比較麻煩的地方。

先從路由開始是一個比較好的方法。大多數人會用頁間動畫切換,這需要一些時間。頁間切換的時候,用戶不太會跟頁面上的元素交互。

下面是一個以路由為基礎的代碼分割例子:

import { BrowserRouter as Router, Route, Switch } from react-router-dom;import Loadable from react-loadable;const Loading = () => <div>Loading...</div>;const Home = Loadable({ loader: () => import(./routes/Home), loading: Loading,});const About = Loadable({ loader: () => import(./routes/About), loading: Loading,});const App = () => ( <Router> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> </Switch> </Router>);

推薦閱讀:

AI 代碼長啥樣?
sqli-labs注入工具(第六關利用注入POC)
你若眼熟,真的純屬巧合。
【實驗】Adversarial Video Generation

TAG:代碼 | 科技 | 計算機科學 |