代码分割
Code Splitting
打包
- 大多数 React 应用都会使用 Webpack、Rollup 或 Browserify 这类的构建工具来打包文件 
- 打包是一个将文件引入合并到一个单独文件的过程,最终形成一个 bundle,接着在页面上引入该 bundle,整个应用即可一次性加载 
代码分割
- 打包是一个非常棒的技术,但随着你得应用的增长,你的代码包也随之增长,尤其是在整合了体积巨大的第三方库的情况下,你需要关注你代码包中所含的代码,以避免因体积过大而导致加载时间过长。 
- 代码分割是诸如 Webpack、Rollup 和 Browserify 这类打包器支持的一项技术,能够创建多个包并在运行时动态加载 
- 对你的应用进行代码分割能够帮助你 “懒加载” 当前用户所需要的内容,能显著的提高你的应用性能 
- 尽管没有减少应用整体的代码体积,但你可以避免加载用户永远不需要的代码,并在初始加载的时候减少所需加载的代码量 
import()
- 在你的应用中引用代码分割的最佳方式是通过动态 import() 语法 - ```jsx harmony 
// 使用之前 import { add } from './math';
console.log(add(16, 26));
// 使用之后 import("./math").then(math => { console.log(math.add(16, 26)) })
* 当 Webpack 解析到该语法时,会自动进行代码分割
    * create React App 和 Next.js 都已经支持该特性而无需进行配置
    * 自己配置 Webpack 的时候需要自己配置
    * 使用 Babel 时,要确保能够解析动态 import 语法而不是将其进行转换,对于这一要求你需要 babel-plugin-syntax-dynamic-import
## React.lazy
* React.lazy 和 Suspense 技术还不支持服务器渲染,如果你想要在使用服务端渲染的应用使用,推荐使用 Loadable Components 这个库,它有一个很棒的服务端渲染打包指南
* React.lazy 函数能让你像渲染常规组件一样处理动态引入的组件
```jsx harmony
// 使用之前
import OtherComponent from './OtherComponent';
// 使用之后
import OtherComponent = React.lazy(() => import('./OtherComponent'))- 此代码将会在组件首次渲染时,自动导入包含 OtherComponent 组件的包 
- React.lazy 接受一个函数,这个函数需要动态调用 import() 它必须返回一个 Promise 该 Promise 需要 reslove 一个 default export 的 React 组件 
- 然后应在 Suspense 组件中渲染 lazy 组件,如此使得我们可以使用在等待加载 lazy 组件时做优雅降级 - ```jsx harmony 
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() { return ( Loading...}> </Suspense> </div> ); }
* Suspense 组件中 可以包裹多个懒加载组件
## 基于路由的代码分割
* 你需要确保选择的分割位置能够均匀地分割代码包,而不会影响用户体验
* 一个不错的选择是从路由开始。大多数网络用户习惯页面之间能够有个加载切换的过程
* 你也可以选择重新渲染整个页面,这样您的用户就不必在渲染的同时再和页面上的其他元素进行交互
```jsx harmony
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
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 Exports
- React.lazy 目前只支持默认导出 default exports - 如果你想要引入的模块使用命名导出,你可以创建一个中间模块,开重新导出为默认模块 
- 保证 tree shaking 不会出错,并且不必引入不需要的组件 - ```jsx harmony 
 
// ManyComponents.js export const MyComponent = / ... /; export const MyUnusedComponent = / ... /;
// MyComponent.js export { MyComponent as default } from "./ManyComponents.js";
// MyApp.js import React, { lazy } from 'react'; const MyComponent = lazy(() => import("./MyComponent.js"));
```
最后更新于
这有帮助吗?
