记一次Webpack构建性能优化
背景
项目技术栈:Vue2.6、Vuex、TS、ClassComponent
整个项目在开发环境启动极其慢,电脑风扇狂转,今天终于受不了了,决定针对性的优化一下
项目当前的构建速度
问题:
- 打包构建出来的资源相当大
- 从开始构建到完成一共用时3分多钟,这已经不能用慢来形容了,那是相当慢!!!
优化策略
合理配置路径解析,优化模块查找的优先级
以下代码默认会最后查找.ts文件,而我们的项目是使用ts书写的,这样的模块查找性能很差
resolve: {
extensions: ['.js', '.vue', '.json', '.scss', '.css', '.less', '.ts']
}
改良后:
resolve: {
extensions: ['.ts', '.js', '.vue', '.json', '.scss', '.css', '.less']
}
优化loader查找文件的范围
合理配置inlcude与exclude属性,满足include条件的模块才会使用对应的loader进行处理,从而减少打包时间,通常情况下node_modules目录下的包都是经过处理的,没必要再次处理。(这里并不是说exclude匹配的文件就不打包了,一样会打包,只是少了loader处理)
{
include: path.resolve(__dirname, 'src'),
}
{
exclude: path.resolve(__dirname, 'node_modules')
}
使用HappyPack开启多线程加速编译
{
test: /\.js$/,
include: path.resolve(__dirname, 'src'),
use: 'happypack/loader?id=babel' // id为唯一值,标识在plugin中需要匹配到的规则
}
new HappyPack({
id: 'babel',
threads: 4,
loaders: ['cache-loader', 'babel-loader']
})
使用cache-loader和happyPackMode
使用thread-loader配合happyPackMode,加速ts文件编译与缓存
在一些性能开销较大的 loader 之前添加 cache-loader,以便将结果缓存到磁盘里。
请注意,保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此 loader。
{
test: /\.tsx?$/,
use: [
{
loader: 'cache-loader'
},
{
loader: 'thread-loader',
options: {
workers: require('os').cpus().length - 1,
},
},
{
loader: 'ts-loader',
options: {
appendTsSuffixTo: [/\.vue$/],
happyPackMode: true
}
}
],
include: path.resolve(__dirname, '../src')
}
经过上述处理后,目前文件打包的时长如下:
虽然还是很慢,但是已经将时间缩短了2/3,收益非常可观
使用DllPlugin
大部分情况下,很多第三方库的代码并不会发生变更(除非是版本升级),这时就可以用到dll:把复用性较高的第三方模块打包到动态链接库中,在不升级这些库的情况下,动态库不需要重新打包,每次构建只重新打包业务代码。
配置webpack.dll.config.js
// 定义常用对象
const path = require('path');
const webpack = require('webpack');
// dll文件存放的目录
const dllPath = '../dist/dll';
module.exports = {
// 需要提取的库文件
entry: {
vue: ['vue', 'vue-router', 'vuex', 'axios'],
},
output: {
path: path.join(__dirname, dllPath),
filename: '[name].dll.js',
// vendor.dll.js中暴露出的全局变量名
// 保持与 webpack.DllPlugin 中名称一致
library: '[name]_dll_[hash]'
},
plugins: [
// 定义插件
new webpack.DllPlugin({
path: path.join(__dirname, dllPath, '[name].manifest.json'),
// 保持与 output.library 中名称一致
name: '[name]_dll_[hash]'
})
]
};
在npm script中添加命令
"dll": "webpack --config build/webpack.dll.config.js"
执行
npm run dll
在webpack.dev.config.js中配置
plugins: [
// 这个插件帮助我们在html中引入dll文件
new AddAssetHtmlWebpackPlugin({
filepath: path.resolve(__dirname, '../dist/dll/vue.dll.js') // 对应的 dll 文件路径
}),
new webpack.DllReferencePlugin({
manifest: require('../dist/dll/vue.manifest.json')
})
]
再次打包
对比之前的 44.1mb 少了 600kb 大小,这个就是打出来的库的大小,当然项目里还有很多其他文件占了很大的空间,还需要进一步优化。
经过所有处理后,最终的开发环境构建时长:
功夫不负有心人,折腾了一晚上,构建速度提升了 6 倍,算是不小的收获吧!
纸上得来终觉浅 绝知此事要躬行
转载自:https://juejin.cn/post/7234817882902347835