代码分割
为了避免打包出大体积的代码包,需要对代码进行分割。代码分割是由Webpack、Rollup等打包器支持的一项技术,能够创建多个代码包并在运行时动态加载,从而提高应用的性能。
尽管总的体积并没有减少,但是可以避免加载用户永远不需要的代码,并减少初始加载时需要加载的代码量,提升首屏加载的性能。
import()
在应用中引入代码分割的最佳方式是通过动态 import() 语法。 当Webpac解析到该语法时,会自动进行代码切割。当使用 Babel 时,要确保 Babel 能够解析动态 import 语法而不是将其进行转换。对于这一要求需要 @babel/plugin-syntax-dynamic-import 插件。
import("./math").then(math => {
console.log(math.add(16, 26));
});
React.lazy()
React.lazy 函数能让你像渲染常规组件一样处理动态引入(的组件)。会在首次渲染时自动导入组件的代码包。
React.lazy 接受一个函数,这个函数需要调用动态 import()。它必须返回一个 Promise,该 Promise 需要 resolve 一个 default export 的 React 组件。
应该在 Suspense 组件中渲染 lazy 组件, 在等待加载 lazy 组件时做优雅降级(如 loading 指示器等)。
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
路由懒加载
我们可以在打包之后,通过切换路由,监控network面板资源的请求情况,验证是否分隔成功。
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</Router>
);