一、缩小文件搜索范围
1. 减少loader处理的文件
loader对文件的转换操作很耗时,因此我们最好精准匹配要转换的文件
loader 可以通过 options 对象配置(仍然支持使用 query 参数来设置选项,但是这种方式已被废弃)。
babel-loader
用于转换ES6代码,文档说了它的几个特点:
- 慢!
- 代码体积变大!
```javascript
// 转换前Vue-Cli默认配置:
{
}test: /\.m?jsx?$/, // 项目中如果只有js文件就写js就好,提高正则表达式性能exclude: [function () { /* omitted long function */ }],use: [/* config.module.rule('js').use('babel-loader') */{loader: 'D:\\CS\\Repositories\\project\\erabbit-pc-vue-project\\node_modules\\babel-loader\\lib\\index.js',options: {cacheCompression: false,cacheDirectory: 'D:\\CS\\Repositories\\project\\erabbit-pc-vue-project\\node_modules\\.cache\\babel-loader',cacheIdentifier: '26fa99d2'}}]
// 修改配置 { test: /.js$/, use: [ { loader: ‘babel-loader’, options: { cacheDirectory: true } } ], include: path.resolve(__dirname, ‘src’) }
<a name="UwKna"></a>## 2. 优化resolve.modules用于配置去哪找第三方模块,默认值是 ['node_modules'],含义是先去当前目录下的 ./node_modules 目录下去找想找的模块,如果没找到就去上一级目录 ../node_modules 中找,再没有就去 ../../node_modules 中找,以此类推<br />当安装的第三方模块都放在项目根目录下的 ./node_modules 目录下时,没有必要按照默认的方式去一层层的寻找,可以指明存放第三方模块的绝对路径,以减少寻找.```javascript// vue-cli默认配置modules: ['node_modules','D:\\CS\\Repositories\\project\\erabbit-pc-vue-project\\node_modules','D:\\CS\\Repositories\\project\\erabbit-pc-vue-project\\node_modules\\@vue\\cli-service\\node_modules']// 修改resolve: {modules: [path.resolve(__dirname, 'node_modules')]}
3. 优化 resolve.mainFields 配置
用于配置第三方模块使用哪个入口文件,与target配置有关。
由于一些第三方模块可能可以支持不同的环境,会有多个不同的入口,但大多数都是以main为入口,不过我觉得这一项还是不要改好。
resolve: {// 只采用 main 字段作为入口文件描述字段,以减少搜索步骤mainFields: ['main'],},
4. 配置resolve.alias
用于配置导入第三方模块时要加载的文件路径,比如一个包有一个入口文件,依赖于很多其它的文件,每次加载都需要去解析所有文件,一般包都会有一份打包好的生产环境的文件,可以配置别名为该文件路径,这样就可以直接加载,但是这样无法配置treeshaking去除重复代码。
5. 优化rsolve.extensions
当省略文件后缀时会采用该配置列表中的后缀去查找,列表越小越好,
// 默认resolve: {// 尽可能的减少后缀尝试的可能性extensions: ['.js', '.json'],},// 修改extensions: ['.js']
6. 优化 module.noParse 配置
用于配置不需要解析的文件,忽略对部分没采用模块化的文件的递归解析处理,这样做的好处是能提高构建性能。如
const path = require('path');module.exports = {module: {// 独完整的 `react.min.js` 文件就没有采用模块化,忽略对 `react.min.js` 文件的递归解析处理noParse: [/react\.min\.js$/],},};
二、thread-loader多进程处理
官方的一个loader(文档)
一般可以用于对babel-loader开启多进程,仅在耗时的操作中使用此 loader!
可能我的项目中js文件不多,感觉没啥提升
// 安装yarn add thread-loader -D// 在耗时的loader如babel-loader前配置即可module: {rules: [{test: /\.js$/,use: [{loader: 'thread-loader'},{loader: 'babel-loader',options: {cacheDirectory: true}}],include: path.resolve(__dirname, 'src')}]},
三、构建速度分析插件
// 安装yarn add -D speed-measure-webpack-plugin// 导入使用const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')const smp = new SpeedMeasurePlugin()configureWebpack: smp.wrap({//...webpack的配置})
打包之后会在控制台输出,
四、使用 ParallelUglifyPlugin
由于压缩 JavaScript 代码需要先把代码解析成用 Object 抽象表示的 AST 语法树,再去应用各种规则分析和处理 AST,导致这个过程计算量巨大,耗时非常多。
插件github
// 安装yarn add webpack-parallel-uglify-plugin -Dconst ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')plugins: [// 使用 ParallelUglifyPlugin 并行压缩输出的 JS 代码new ParallelUglifyPlugin({// 传递给 UglifyJS 的参数uglifyJS: {output: {// 最紧凑的输出beautify: false,// 删除所有的注释comments: false},compress: {// 在UglifyJs删除没有用到的代码时不输出警告,这一项报错说不支持wrnings// warnings: false,// 删除所有的 `console` 语句,可以兼容ie浏览器drop_console: true,// 内嵌定义了但是只用到一次的变量collapse_vars: true,// 提取出出现多次但是没有定义成变量去引用的静态值reduce_vars: true}}})]
配置完打包发现时间反而上去了,插件自己就花了一秒多。
