代码分隔我们现在大多数React项目都是以Webpack 或者 Browserify等将一堆的jsx文件组织一起,并且由一个类似index.js的入口文件串联起来的单页面web页面。例如:// math.jsexport function add(a, b) { return a + b;}App:// app.jsimport { add } from ‘./math.js’;console.log(add(16, 26)); // 42打完包后:function add(a, b) { return a + b;}console.log(add(16, 26)); // 42从这个例子可以看出,打完包后将所有的js都压缩到一个文件里了。随着项目越来越大,打包的文件也会越来越大,如果再引入一些第三方的js库,那就更庞大了。接下来介绍一下如何将React代码分隔。(以下内容是16.6.0版本才支持的)Code Splitting会帮助你的应用实现lazy load.这么做,即使没有减少整个项目的代码量,也会避免在项目初始加载时,加载没必须的js,从而使用项目性能有所提升。import()最简单直接的方式就是引入动态 import 实现代码分隔。使用 动态 import 之前:import { add } from ‘./math’;console.log(add(16, 26));使用动态 import 后:import("./math").then(math => { console.log(math.add(16, 26));});注意,动态 import 并不是标准的EcmaScript,所以需要配置 babel-plugin-syntax-dynamic-importReact.lazyReact.lazy 可以以一个React标准组件的方法渲然一个动态引入的组件。以前的做法:import OtherComponent from ‘./OtherComponent’;function MyComponent() { return ( <div> <OtherComponent /> </div> );}使用 React.lazy :const OtherComponent = React.lazy(() => import(’./OtherComponent’));function MyComponent() { return ( <div> <OtherComponent /> </div> );}这样在组件MyComponent渲然的时候才加载OtherComponent。React.lazy 必须使用动态 import() 引入组件,必须返回一个 Promise Component。React.lazy 目前不支持服务端渲然Suspense假如在 React.lazy 时,import 失败或者异常时,我们需要给于提示,或者一个默认的组件,我们就需要使用 Suspense .例如:const OtherComponent = React.lazy(() => import(’./OtherComponent’));function MyComponent() { return ( <div> <Suspense fallback={<div>Loading…</div>}> <OtherComponent /> </Suspense> </div> );}fallback 也是一个组件,但不能通过 动态 import 引入的组件.Suspense 只能包裹一个单结点,如果有多个 动态 import 的组件需要放在一个 Suspense 中时,可以使用类似 React.Fragmet 包裹一下,也可以使用其他的 React 组件包裹。例如:const OtherComponent = React.lazy(() => import(’./OtherComponent’));const AnotherComponent = React.lazy(() => import(’./AnotherComponent’));function MyComponent() { return ( <div> <Suspense fallback={<div>Loading…</div>}> <section> <OtherComponent /> <AnotherComponent /> </section> </Suspense> </div> );}基于Router的代码分隔基于 Router 的代码分隔,也是我们通常所说的按需加载。是我们推荐的方式。例如:import { BrowserRouter as Router, Route, Switch } from ‘react-router-dom’;import React, { Suspense, lazy } from ‘react’;const Home = lazy(() => import(’./routes/Home’));const About = lazy(() => import(’./routes/About’));const App = () => ( <Router> <Suspense fallback={<div>Loading…</div>}> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> </Switch> </Suspense> </Router>);Named ExportsReact.lazy 目前只支持 default 导出,不支持命名导出。例如,只支持:export default () => { return(<div>I am a Lazy component</div>);}如果要支持命令导出,需要重新再 export ,例如:// ManyComponents.jsexport const MyComponent = /* … /;export const MyUnusedComponent = / … */;// MyComponent.jsexport { MyComponent as default } from “./ManyComponents.js”;// MyApp.jsimport React, { lazy } from ‘react’;const MyComponent = lazy(() => import("./MyComponent.js"));推荐阅读 《React 手稿》