webpack包教不包会(二)性能优化最佳实践
在第一篇我们实现了一个基于react的webpack配置,只是满足了我们基本的开发需求,你肯定曾经或正在遭受webpack冷启动和热更新龟速,打包时间过久的痛苦,那么这篇我们来总结一些,如何使它打包
更快
,更小
,让我们的老伙计爆发出更强的战斗力。
小即是快!
如果你装的包有问题,可能是版本不兼容,真的坑...
开发阶段性能优化
监控面板
清晰的展示打包的效果,让我们更快的定位到问题的位置,给出明确的优化建议
speed-measure-webpack-plugin
速度分析(webpack5到目前还不支持),使用smp.wrap包裹。
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();
const webpackConfig = smp.wrap({
plugins: [
new MyPlugin(),
new MyOtherPlugin()
]
});
打包时控制台能看到具体耗时
webpack-bundle-analyzer
生成一个漂亮的分析图(可以查看开启gzip之后的大小)
开启通知
webpack-build-notifier
打包结束之后可以给出提示
plugins: [
new WebpackBuildNotifierPlugin({
title: "爸爸,打包成功了",
suppressSuccess: true, // don't spam success notifications
}),
]
开启多核压缩
uglifyjs-webpack-plugin 官方推荐
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
optimization: {
minimizer: [
new UglifyJsPlugin({
parallel: true, // 开启多核
}),
],
},
};
开启打包进度监控
progress-bar-webpack-plugin
打包时会显示打包进度
清晰的开发面板
webpack-dashboard
打开一个清晰的监控面板
上线阶段
前端缓存负载(性能优化杀手锏)
知道什么时候可以去更新离线缓存
// npm install webpack-nano webpack-manifest-plugin --save-dev
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const options = { ... };
module.exports = {
// an example entry definition
entry: [ 'app.js' ],
...
plugins: [
new WebpackManifestPlugin(options)
]
};
1、在dist文件下,生成一个mainfest.json的文件,做打包记录
2、利用 client 的长效缓存机制,命中缓存来消除请求,并减少向 server 获取资源,同时还能保证 client 代码和 server 代码版本一致。我们可以使用缓存功能
optimization: {
runtimeChunk: 'single',
splitChunks: {
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors',
chunks: 'all',
},
},
},
},
加载loading
html-webpack-plugin
这个生成模版html时用到
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
title: 'webpack包教不包会(一)',
template: './src/index.html',
loading: {
html: '加载中...'
}
}),
],
// 模版html中引用
<body>
<div id="root">
<%= htmlWebpackPlugin.options.loading.html %>
</div>
</body>
分析打包结果
webpack-chart(官方推荐)
使用
// package.json 配置命令
"chart": "webpack --profile --json > stats.json"
根目录下生成stats.json
会生成一个可交互饼图
或者使用官方分析工具(除了丑还挺好用的)
缩小文件范围
test exculde include
{
// 用正则去匹配要用该 loader 转换的 CSS 文件
test: /\.less$/,
use:['style-loader', 'css-loader', 'less-loader'],
exclude: /node_modules/,
include: './src'
},
压缩
项目上线,一键压缩代码,图片处理 js、css happypack ts-loader optimize-css-assets-wenpack-plugin
配置多入口
可以用于获取更小的 bundle,以及控制资源加载优先级
entry: {
index: './src/index.js',
another: './src/another-module.js',
},
提取公共模块
SplitChunksPlugin
optimization: {
splitChunks: {
chunks: 'all',
},
},
mini-css-extract-plugin
用于将 CSS 从主应用程序中分离。
预获取/预加载模块
在引用时
-
prefetch(预获取):将来某些导航下可能需要的资源 -
preload(预加载):当前导航下可能需要资源
import(/* webpackPrefetch: true */ '模块地址');
import(/* webpackPreload: true */ '模块地址');
treeShaking 自动剔除无用代码
在webpack4之后的版本,mode设置production会自动进行treeshaking
对于treeShaking的解释,官网用了很形象的一个例子
你可以将应用程序想象成一棵树。绿色表示实际用到的 source code(源码) 和 library(库),是树上活的树叶。灰色表示未引用代码,是秋天树上枯萎的树叶。为了除去死去的树叶,你必须摇动这棵树,使它们落下。
总结
参考资料
wepack中文文档 https://webpack.docschina.org/guides/getting-started/
深入浅出 Webpack http://webpack.wuhaolin.cn/
关注「 前端时空 」
传递一线全栈技术,与你一起穿越前端时空