前言
欢迎关注同名公众号《熊的猫》,文章会同步更新!
在日常开发中,最容易让人注意的就是项目编译打包的时间,特别是在较频繁打包部署时,这个时间显得很漫长。
例如:之前接手的一个项目 "冷启动" 时编译过程花费了约 86 秒:
这能忍吗?显然不能,于是打算将其进行优化,否则太影响开发体验了,下面就是在优化过程中做的一些处理。
分析耗时模块
查看 vue-cli 内置配置
使用 vue-cli-service inspect 可以很方便的查看 vue-cli 内置的配置内容,在终端输入:vue inspect --mode production webpack.config.production.js,就会在项目和 src 同级目录中生成 webpack.config.production.js 文件.
分析工具
要得到耗时的模块,那就需要用到一些分析工具了,例如:
speed-measure-webpack-plugin
这个插件可以测量网页包构建速度,并会输出各个模块编译的时长,可以帮助我们更好的找到耗时模块。
在 vue.config.js 配置
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); module.exports = { ..., configureWebpack: (config) => { ... config.plugins.push( new SpeedMeasurePlugin(), ); }, }; 复制代码
重新启动
从下图面的输出结果中,很容易看到对应的耗时模块.
webpack-bundle-analyzer
这个插件以可视化网页包输出文件的大小,并且提供了交互式可缩放的树形图.
在 vue.config.js 配置
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); + const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { ..., configureWebpack: (config) => { ... config.plugins.push( new SpeedMeasurePlugin(), + new BundleAnalyzerPlugin() ); }, }; 复制代码
重新启动
从下图面的输出结果中,可以很容易的观察出每个模块打包后的大小.
优化
thread-loader —— 开启多线程优化
根据 speed-measure-webpack-plugin 输出的编译时间显示,以下几个 loader 编译时间比重较大:
- vue-loader
- ts-loader
- babel-loader
- image-webpack-loader
- postcss-loader 关于这一部分就可以通过 thread-loader 进行优化,因为它能将这些非常耗时的内容单独放到另一个线程中执行,但并不是针对所有的 loader 都做这个处理,因为这个处理本身也是有较大的开支。
注意:仅在耗时的操作中使用 thread-loader,否则使用 thread-loader 会后可能会导致项目构建时间变得更长,因为每个 worker 都是一个独立的 node.js 进程,其开销大约为 600ms 左右,同时还会限制跨进程的数据交换等。
在回顾下前面,没有使用 thread-loader 前项目的 "冷启动" 时间约 86 秒:
只针对 babel-loader 使用 thread-loader 后项目的 "冷启动" 时间约 78 秒:
PS:在对其他 loader 使用 thread-loader 发现时间更长,因此取尝试后的最优结果
hard-source-webpack-plugin —— 使用缓存优化
webpack 中几种缓存方式:
cache-loaderhard-source-webpack-pluginbabel-loader 的 cacheDirectory 标志
以上这些缓存方式都有首次启动时的开销,即它们会让 "冷启动" 时间会更长,但是二次启动能够节省很多时间.
而 vue-cli 已经内置了 cache-loader 和 babel-loader 的 cacheDirectory 标志,其中对应的配置如下:
默认情况下的 "二次启动" 时间约为 38 秒,原因是 "冷启动" 时已经将 babel-laoder、ts-loader、vue-loader 进行了缓存:
先配置 hard-source-webpack-plugin 插件:
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + const HardSourceWebpackPlugin = require('hard-source-webpack-plugin'); module.exports = { ..., configureWebpack: (config) => { ... config.plugins.push( // 为模块提供中间缓存,缓存路径是:node_modules/.cache/hard-source // 解决未检测到的配置更改 + new HardSourceWebpackPlugin({ root: process.cwd(), directories: [], environmentHash: { root: process.cwd(), directories: [], // 配置了files 的主要原因是解决配置更新,cache 不生效了的问题 // 配置后有包的变化,plugin 会重新构建一部分 cache files: ['package.json', 'yarn.lock'] } }), new SpeedMeasurePlugin(), new BundleAnalyzerPlugin(), ); }, }; 复制代码
使用 hard-source-webpack-plugin 后的 "冷启动" 和 "二次启动" 时间如下:
减少打包体积
减少 js 代码体积
在打包之后的 dist 目录下,查找对应的 console.log,结果如下:
可以发现 vue-cli 中默认的配置并没有将 js 文件中的一些 console.log 语句进行删除,因此这也是一些可以继续优化的内容.
这里可以通过 uglifyjs-webpack-plugin 或 terser-webpack-plugin 插件来删除注释和压缩 js 代码,具体配置可以直接点链接进行查阅.















