共计 3643 个字符,预计需要花费 10 分钟才能阅读完成。
背景
本文接上篇:
上文中,咱们理解了 chunks 三个字段的含意,以及每个字段对应的行为。
明天是实际篇。
批改短短几行配置,就达到了数百毫秒的优化成果。
注释
我的这个我的项目,迭代一年多了,两头打包配置也没没怎么改过,毕竟也没什么问题,速度也还能够。
刚好最近老板要搞指标,让每个项目组剖析性能数据,给优化计划,做性能优化。
不剖析不晓得,一剖析,很快啊,马上就看出了问题, 看包剖析后果:
脑海里霎时闪过一张图:
简直所有的三方依赖都打在了一起,写好的页面按路由加载也都打到了一起, 几乎辣眼睛 …
于是就去看了一下代码配置:
修改前
原始配置:
const OnBoard = React.lazy(() => import('@/pages/onboard'));
const menuData = MenuItemTypes[] = [
{
title: 'onboard',
path: '/onboard',
meta: {showInMenu: false},
children: [
{
component: OnBoard,
// ...
},
// ...
]
},
// ...
];
const AppRouter = () => {
// ...
const {el, routes} = getRoutes(menuData);
// ...
return (<BasicLayout {...matchedRoute.meta}>
<Suspense fallback={<Spin />}>
<Route path="/" exact component={MyDashboard} />
{el}
</Suspense>
// ...
</BasicLayout>
);
};
const App: React.FC<> = () => {
// ...
return <AppRouter />;
};
const AppContainer = () => (<Router history={history}>
<Provider store={store}>
<Locale>
<App />
</Locale>
</Provider>
</Router>
);
看起来没什么问题。
看了一下 webpack 配置:
optimization: {
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
cacheGroups: {
vendor: {test: /[\\/]node_modules/,
enforce: true,
priority: 5,
},
antd: {test: /[\\/]node_modules[\\/]antd[\\/]/,
priority: 10,
},
antdIcons: {test: /[\\/]node_modules[\\/]@ant-design[\\/]/,
priority: 15,
},
styles: {test: /\.(scss|css)$/,
minChunks: 1,
reuseExistingChunk: true,
enforce: true,
priority: 20,
},
},
},
},
看起来貌似也没什么问题。。。
build 之后 html 中的脚本,乍一看如同也没故障 …
<script type="text/javascript" src="/main.75a8d9f8.js"></script>
<script type="text/javascript" src="/chunk.styles~main.eaa8f358.js"></script>
<script type="text/javascript" src="/chunk.antdIcons~main.6ee35491.js"></script>
<script type="text/javascript" src="/chunk.vendor~main.aa82abbc.js"></script>
<script type="text/javascript" src="/chunk.main.db1b67a1.js"></script>
这种状况下,批改 chunks
配置的比照:
chunks: all
包剖析:
加载工夫以及入口文件初始加载的脚本文件:
chunks: async
:
<script type="text/javascript" src="/main.64245819.js"></script>
<script type="text/javascript" src="/chunk.main.d6a
简直没有什么变动,一时间,开始狐疑是不是受了其余配置的影响,就去认真去找了一下,果然:
速度批改了配置。
修改后:
chunks:all
optimization: {
runtimeChunk: {name: 'manifest',},
splitChunks: {
chunks: 'all',
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
cacheGroups: {
vendor: {test: /[\\/]node_modules/,
enforce: true,
priority: 5,
},
antd: {test: /[\\/]node_modules[\\/]antd[\\/]/,
priority: 15,
enforce: true,
},
antdIcons: {test: /[\\/]node_modules[\\/]@ant-design[\\/]/,
priority: 15,
enforce: true,
},
antdV: {test: /[\\/]node_modules[\\/]@antv[\\/]/,
priority: 30,
enforce: true,
},
bizcharts: {test: /[\\/]node_modules[\\/]bizcharts[\\/]/,
priority: 20,
enforce: true,
},
dplayer: {test: /[\\/]node_modules[\\/]dplayer[\\/]/,
priority: 25,
enforce: true,
},
styles: {test: /\.(scss|css|less})$/,
minChunks: 1,
reuseExistingChunk: true,
enforce: true,
priority: 20,
},
'react-dom': {test: /[\\/]node_modules[\\/]react-dom[\\/]/,
priority: 25,
enforce: true,
},
'rc-components': {test: /([\\/]node_modules[\\/]rc-[a-zA-Z-]+[\\/])/,
priority: 25,
enforce: true,
},
},
},
},
很快啊,马上就有了变动:
chunks: async
入口文件初始加载的脚本:
<script type="text/javascript" src="/main.572fc9fe.js"></script>
<script type="text/javascript" src="/chunk.main.8c0dcc22.js"></script>
除了入口脚本数量的变动,总体积,加载时长,简直没有变动。
脚本数量的不同:
all
: 8async
: 4
区别就是,大文件的体积不同,对这个大文件的加载工夫有影响。
回头看,这是一个 maxChunks
配置谬误引发的血案。
修改配置之后,空谷传声。
依据不同场景正当的拆分
依据你的状况,能够抉择更适宜的打包策略。
all
的劣势在于,能共享代码。
Providing
all
can be particularly powerful, because it means that chunks can be shared even between async and non-async chunks.
抉择这个模式,如果你用的协定是 h2, 并行下载,可能有比拟好的成果。
async
会帮你合并一些包,但产生的申请也会缩小。
须要依据理论状况做测试,抉择最适宜的打包策略。
还有一种宰割策略:
基于路由的宰割 vs 基于组件的宰割
打包的状况也会不同,比照如下两幅图:
和:
理论的场景中,不会严格的辨别这两种,能够一起用。
比方,个别状况下,一个页面就是一个模块,它的子页面,也是一个模块,而这两者是离开的。
也就是更贴近这个模型:
当然一些非凡的场景下,也能够对某些性能组件去宰割,比方播放器组件,代码块组件等。
这个时候的组件,会独自成包,应用的时候才去加载。
这是另一个话题了,也有很多细节在外面,本篇就不过多介绍。
总结
具体,还是要依据不同的场景,抉择不同的打包策略,来达到最有成果。
webpack 也提供了具体的文档:
https://webpack.docschina.org…
理论用到的时候能够去看看。
内容就这么多,心愿对大家有所启发。
谢谢。