webpack性能优化(一)优化打包速度

565 阅读1分钟
文章开头第一句加入:本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

1.编译缓存

babel-loader

要转换的js是比较费时间的,将babel编译过的文件缓存起来,下次只需要编译更改过的代码文件。这样可以大大减少打包时间。 babel-loader?cacheDirectory=true

cache-loader

将 loader 的编译结果写入硬盘缓存。再次构建会先比较一下,如果文件较之前的没有发生变化则会直接使用缓存

module:{
    rules:[
        {
            test:/\.js$/,
            use:[{
                    loader:'cache-loader'.
                    cacheDirectory:'./cache'
            },...loaders]
        }
    ]
}

2.缩小范围

通过exclude、include 缩小搜索范围

module.exports = {
    module:{
        rules:[
            {
                test:/.vue$/,
                loader:'vue-loader',
                // 只在src文件夹中查找
                include:[resolve('src')],
                // 排除的路径
                exclude:/node_modules/
            }
        ]
    }
}

利用resolve 字段配置

extensions 

webpack会根据extensions定义的后缀查找文件(频率较高的文件类型优先写在前面)

alias

减少搜索范围我们可以直接告诉webpack去哪个路径下查找

    resolve:{
        alias: {
            'vue$': 'vue/dist/vue.runtime.esm.js',
        },
        extensions: ['.js','.json','.vue']
    }

3.忽略打包

ignorePlugin(不引入)

打包时忽略某文件

new webpack.IgnorePlugin({
  resourceRegExp: /^./locale$/,
  contextRegExp: /moment$/,
});

然后再手动引用我们用到的中文格式 import 'moment/locale/zh-cn'

noParse (不解析)

像vue.min.js,jqery这种本身我们认为不会引用其他的包,且压缩过的。可以不去解析,增加打包速度。 noParse: /jquery/

4.多进程打包

happyPack 或者 thread-loader(官方推荐)开启多进程打包。 loader解析转换以及代码的压缩中耗费时间较多,转换的文件数据量也是非常大。由于js单线程的特性不能并发处理这些文件。这时我们开启多进程打包,减少构建时间。

{
  test: /.js$/,
    user: [
      {
        loader: 'thread-loader',
        options: {
          workers: 3
        }
      },
      'babel-loader'
    ]
}

同时注意,进程本身有开销,如果loader时间本身很短,反而起到反作用。

5.多进程压缩

压缩同样可以开启多进程,parallel-uglify-plugin或者terserWebpackPlugin。

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        parallel: 4,
      }),
    ],
  },
};

6.分包

使用externals选项

externals选项可以排除指定的第三方模块,在构建过程中忽略它们。然后使用cdn单独引用

module.exports = { 
    //... 
    externals: { jquery: 'jQuery' } 
};
预编译,用DLLPlugin和DllReferencePlugin

它可以帮你在本地提前打包好指定库,然后在项目再次打包的时候直接从本地引入而不需要再次打包。

// webpack.dll.config.js 分包
const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    jquery: [
      'jqery'
    ]
  },
  output: {
    filename: '[name].dll.js',
    path: path.resolve(__dirname, './build/dll'),
    library: '[name]'
  },
  plugins: [
    new webpack.DllPlugin({
      name: '[name]',
      path: './build/dll/[name].json'
    })
  ]
};

// webpack.config.js DllReferencePlugin引用映射文件
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require('./build/dll/manifest.json')
    })
  ]
};