背景
使用 weex-toolkit 作为脚手架新建 weex 的项目,在项目规模越来越大是,每一次修改文件,编译会越来越慢。answer 这个项目 vue 组件众多 (30+),每次即便一个组件的文案修改,也会长达 30s 的时间。观察到,用时最多的时间在 asset optimization 上
在 google 搜了下,发现也有同学遇到了相同的问题:
https://github.com/weexteam/weex-toolkit/issues/315
分析
难道我们修改一个文件,所有文件的编译都要走一遍?通过 webpack 输出的信息并不是这样
修改一个文件,只有一个 vue 做了编译,速度很快,和 asset optimization 没有多大关系,那问题可能会出现在哪里?
weex 脚手架提供的是多页开发的方式,会给每一个 vue 文件都是一个 entry,都会生成对应的 html 去预览这个组件。
const getEntryFile = (dir) => {
dir = dir || '.';
const directory = helper.root(dir);
fs.readdirSync(directory).forEach((file) => {
const fullpath = path.join(directory, file);
const stat = fs.statSync(fullpath);
const extname = path.extname(fullpath);
if (stat.isFile() && extname === '.vue') {
const name = path.join(dir, path.basename(file, extname));
if (extname === '.vue') {
const entryFile = path.join(vueWebTemp, dir, path.basename(file, extname) + '.js');
fs.outputFileSync(entryFile, getEntryFileContent(entryFile, fullpath));
webEntry[name] = entryFile;
}
weexEntry[name] = fullpath + '?entry=true';
}
else if (stat.isDirectory() && file !== 'build' && file !== 'include') {
const subdir = path.join(dir, file);
getEntryFile(subdir);
}
});
}
在 preview.html 页面上,也可以切换不同的 button 去预览不同的组件。
会不会是时间大多数时间都耗费在这上面呢?
在排查的过程中,这个帖子引起了我的注意
https://www.v2ex.com/t/419797
8396ms asset optimization
95% emitting
大多数时间都花在了 asset optimization 上,下面也提出,
https://github.com/mzgoddard/hard-source-webpack-plugin 做了优化
和 html-webpack-plugin 的 diff:
大概思路就是设置一个变量,如果这个之前编译过,为 true,如果有修改其为 false。当 true 的时候跳过再次编译。
在项目中试了一下,果然提升了很大。
优化前:
优化后:
总的编译时间提升了 95%,罪魁祸首应该就是这个了。
给 weex 的 webpack 模板提交了个PR
https://github.com/weex-templates/webpack/pull/5,大家用最新版不会遇到编译时间长的问题了。
反思
-
直接另外开一个库去加这个功能,很难做到和父库的同步,这样很难去做以后的升级(比如要升级到 webpack@4)
-
给所有 vue 组件都生成 html ,这种方式到底好不好呢?多页的这个页我觉得不应该是按照组件去划分,而是规范一下,只有 src 一级目录下的 vue 才是入口?这样最多也没几个,速度也不会慢下来
-
如果想更快点,也可以加上 https://github.com/mzgoddard/hard-source-webpack-plugin 这个插件,会把之前编译的结果缓存到硬盘里,如果重复的就不会重新去编译了