初始打包时间:
初始包体积:
1. 包分析工具
插件使我们能够更直观的看到每个包的大小以及构建时长。
1-1. 插件
webpack-bundle-analyzer:这会生成一个视图,以便更直观的观察包
speed-measure-webpack-plugin
1-2. 安装
npm install webpack-bundle-analyzer --save-dev
npm install speed-measure-webpack-plugin --save-dev
更改package.json中的build
"scripts": {
"build": "vue-cli-service build --report",
},
2. 以CDN形式引入公共依赖
使用 externals 提取这些依赖包,在打包时忽略它们,就不会再打到 chunk-vendors.js里边;
更改为以CDN的形式引入。
module.exports = {
transpileDependencies: true,
productionSourceMap: true,
publicPath: './',
configureWebpack: {
// 提取公共依赖
externals: {
vue: 'Vue',
'element-ui': 'ELEMENT'
},
plugins: [
new BundleAnalyzerPlugin(),
new SpeedMeasurePlugin(),
],
},
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
注意:这里演示的将elementUI提取出来,只是为了演示。正常开发中,最佳实践为按需引入(使用了哪些就引入哪些)
3. 开启代码压缩
开启压缩有两种方式:
a. 在打包时压缩,当请求网页时,会返回对应的.gz文件;
b. 在nginx中配置,请求网页时,由服务器进行压缩。
建议使用第一种,第二种需要消耗服务器的 CPU 资源。
3-1. 插件
compression-webpack-plugin
3-2. 安装
npm install compression-webpack-plugin --save-dev
本地项目配置
const CompressionPlugin = require('compression-webpack-plugin'); // 代码压缩
module.exports = {
configureWebpack: {
plugins: [
new CompressionPlugin(
{
algorithm: "gzip",
test: /\.(js|css)$/, // 匹配的文件类型
threshold: 10240, // 对10k以上的文件压缩
// 是否删除源文件,这里不要删除源文件哈。
// 因为nginx中是找对应js的gz文件,如果删除,会导致ng找不到对应文件,从而页面加载失败。
deleteOriginalAssets: false,
minRatio: 0.8, // 压缩比
}
),
],
},
}
服务器上的nginx配置:
http {
# ......
# 开启nginx_static后,对于任何文件都会先查找是否有对应的gz文件。
gzip_static on;
# ......
}
怎么判断配置压缩生效?
响应标头中的 Content-Encoding 为 gzip 时说明配置生效。
4. production环境不生成SourceMap
module.exports = {
productionSourceMap: process.env.NODE_ENV !== 'production',
configureWebpack: {
// ......
},
}
5. Happywebpack(开启多线程打包)
开启多线程打包这一步在大型项目中的效果最为显著。
5-1. 插件
HappyPack
5-2. 安装
npm install happypack --save-dev
const HappyPack = require('happypack');
const os = require('os');
// 开辟一个线程池,拿到系统CPU的核数,happypack 将编译工作利用所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
configureWebpack: {
plugins: [
new HappyPack({
id: 'happybabel',
loaders: ['babel-loader'],
threadPool: happyThreadPool
})
],
},
}
------------------------ 结束 ------------------------
完整配置
const path = require('path');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; // 包分析(会提供一个网页视图,更直观的观察包的体积信息)
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin"); // 包分析
const CompressionPlugin = require('compression-webpack-plugin'); // 代码压缩
const HappyPack = require('happypack');
const os = require('os');
// 开辟一个线程池,拿到系统CPU的核数,happypack 将编译工作利用所有线程
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
module.exports = {
transpileDependencies: true,
productionSourceMap: process.env.NODE_ENV !== 'production',
publicPath: './',
configureWebpack: {
externals: {
vue: 'Vue',
'element-ui': 'ELEMENT'
},
plugins: [
new BundleAnalyzerPlugin(),
new SpeedMeasurePlugin(),
new CompressionPlugin(
{
algorithm: "gzip",
test: /\.(js|css)$/, // 匹配的文件类型
threshold: 10240, // 对10k以上的文件压缩
deleteOriginalAssets: false, // 是否删除源文件,这里不要删除源文件哈,因为nginx中是找对应js的gz文件,如果删除,会导致ng找不到对应文件,从而页面加载失败。
minRatio: 0.8, // 压缩比
}
),
new HappyPack({
id: 'happybabel',
loaders: ['babel-loader'],
threadPool: happyThreadPool
})
],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
}
},
},
}
优化结果
优化后打包时间:
打包时长:11.33s ==> 3.54s
打包时长缩短:69%
优化后包体积:
打包体积:5.63M ==> 954KB
减少体积:83%
还有很多优化方式,后续再记录上去,拜了个拜!