最近开发的时候遇到一个问题:当项目愈来愈大的时候,webpack构建和编译的速度变得很慢。尽管webpack4官方宣称速度提升了90%以上,但实际使用的时候感受速度和webpack2也差很少。我实在受不了热加载的时候要等几秒才能编译好,因而就开始了优化之路。
最终优化的效果不错,提速达到了80%以上。一路上按着之前作实验的思惟去优化,经历了各类问题,相比于分享解决问题的方法,我反而更想分享下解决问题的思路。html
通常作实验以前,咱们都要先定一个目标。
可是问题来了,虽然感受很慢,但我不知道具体花了多少时间,慢是慢在哪里,因此也没办法知道咱们能够优化到什么程度,优化也无从下手了。 因而首要的任务就是得到webpack编译过程的信息。
在webpack的官方文档中找了一大圈后,发现了配置中devServer.stats属性能够得到编译过程的完整信息node
stats: {
timings: true,
modules: false,
assets: false,
entrypoints: false,
assetsSort: 'field',
builtAt: false,
cached: false,
cachedAssets: false,
children: false,
chunks: false,
chunkGroups: false,
chunkModules: false,
chunkOrigins: false,
performance: true,
errors: true,
warnings: true,
},
复制代码
配成这样以后获得了构建和编译的时间:webpack
目前的项目是多入口的项目,每一个入口之间没有太多的关联,可是却放在了一块儿打包和编译。咱们平时开发的时候若是每次只编译一个入口的文件会不会快一点呢?
本来有三个入口,只加载一个入口的时候能够看到:git
"scripts": {
"dev": "webpack-dev-server --config ./webpack.config/dev.js --hot --inline",
"teacher": "app=teacher webpack-dev-server --config ./webpack.config/dev.js --hot --inline",
"student": "app=student webpack-dev-server --config ./webpack.config/dev.js --hot --inline",
"home": "app=home webpack-dev-server --config ./webpack.config/dev.js --hot --inline",
}
复制代码
在package.json中dev命令前加了一个app=XXX的参数github
const teacherEntry = {
ueditor: [
'babel-polyfill',
'./src/common/UEditor/ueditor.config.js',
'./src/common/UEditor/ueditor.all.js',
'./src/common/UEditor/kityformula-plugin/addKityFormulaDialog.js',
'./src/common/UEditor/kityformula-plugin/getKfContent.js',
'./src/common/UEditor/kityformula-plugin/defaultFilterFix.js'
],
teacher: ['./src/app/teacher/index.js'],
teacherLogin: './src/app/teacherLogin/js/teacherLogin.js'
};
const studentEntry = {
student: ['babel-polyfill', './src/app/student/index.js'],
studentLogin: './src/app/studentLogin/js/studentLogin.js'
};
const homeEntry = {
home: './src/app/home/index.js'
};
const entryObj = {
teacher: teacherEntry,
student: studentEntry,
home: homeEntry
};
const entry = process.env.app
? entryObj[process.env.app]
: Object.assign({}, teacherEntry, studentEntry, homeEntry);
复制代码
而后在webpack.base.config.js中加上了根据process.env.app的值来加载不一样入口的代码,这样就实现开发时跑不一样的命令加载不一样入口的效果了。web
接下来就用控制变量的方法去逐个去掉webpack的loader和plugin,而后观察减小的时间了。json
new WriteFilePlugin({
test: /^((?!hot-update).)*$/
}),
复制代码
发现用到了一个写入文件的插件,将全部文件都写到出口了,但实际上只须要写入html文件就好了,因而改为缓存
new WriteFilePlugin({
test: /\.html$/,
useHashIndex: true
}),
复制代码
改后构建和编译时间变成了30s和3s,有了一点点优化。
而后发现babel编译js的时候没有忽略掉node_modules目录。bash
{
test: /\.js$/,
include: /(src|node_modules\/flv.js)/,
exclude: /(node_modules)/,
loader: 'babel-loader'
},
复制代码
加上后发现时间变成了27s和2.2s,已是一开始的一半了。babel
配置看得差很少了,没有再发现有问题的地方了,因而开始google查找别人的优化方法。
后来找到了一个相似的项目用了happypack(多线程编译)和cache-loader(缓存),感受优化效果还不错:
new HappyPack({
id: 'babel', // 对于loaders id
loaders: ['cache-loader', 'babel-loader?cacheDirectory'], // 是用babel-loader解析
threadPool: happyThreadPool,
verboseWhenProfiling: true // 显示信息
}),
复制代码
加上了happypack和cache-loader以后能够看到第一次构建速度有了很大的提高,减小到了13.5s!
可是编译的速度基本没什么变化,仍是2s。革命还没有成功,同志仍需努力啊。
要进一步优化编译的速度,只好去分析编译的过程到底发生了什么问题了。
将stats中的assets设置为true,观察编译的文件:
devtool: 'cheap-module-eval-source-map'
复制代码
改完后试了一下,构建和编译时间缩短为11s和0.8s。
通过这一路的优化以后,深感webpack的配置博大精深。每一个项目可能都有不一样的问题影响着webpack的速度,因此在此分享定位问题的思路,但愿能帮助遇到相似问题的朋友一步步找到问题,提升速度。
Author: Brady