webpack打包性能优化之一

最近项目需求不是很紧张,本想着活动一下筋骨,放松放松,然而公司项目组很合时宜的召集前端开了一个小会,议题就是谈一谈目前项目中存在哪些问题,并针对存在的问题有没有方案进行改进、优化...

在这其中就谈到了webpack打包慢的问题,目前项目中用到的webpack是4.8.1版本,相比之前的版本可以说性能已经提高很多了,但是还存在一些不令人很满意的地方,比如说第一次打包的时候竟然耗时72394ms,将近一分多钟,连续重复几次,耗时只会多不会少(每次需要把node_modules删掉以保证准确性),如是看看有没有什么方式能提高打包速度,别说还真发现了一些可优化的地方

目前项目中使用的打包压缩工具是webpack默认的UglifyJS插件,它使用的是单线程压缩代码,也就是说当多个js文件需要被压缩时,它需要将文件一个一个进行压缩。因此在正式环境中打包压缩代码就显得非常慢(因为压缩JS代码需要先把代码解析成用Object抽象表示的AST语法树,再去应用各种规则分析和处理AST,导致这个过程耗时非常大)

const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

new UglifyJsPlugin({
    cache: true,
    parallel: true,
    sourceMap: false
})
复制代码

那有没有一种多线程或者是多进程的打包工具呢,别说还真有,这就是:webpack-parallel-uglify-plugin,当webpack有多个JS文件需要压缩和输出时,原来使用UglifyJS去一个个压缩并输出,相比UglifyJS,ParallelUglifyPlugin插件则会开启多个子进程,将多个文件压缩的工作分配给多个子进程去完成,但每个子进程还是通过UglifyJS去压缩代码,无非就是变成了并行处理的多个子任务,效率显然会提高很多。

首先 安装 webpack-parallel-uglify-plugin 插件:

npm i -D webpack-parallel-uglify-plugin
复制代码

配置如下:

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');

module.exports = {
  plugins: [
    new ParallelUglifyPlugin({
      uglifyJS: {
        output: {
          /*
           是否输出可读性较强的代码,即会保留空格和制表符,默认为输出,为了达到更好的压缩效果,
           可以设置为false
          */
          beautify: false,
          /*
           是否保留代码中的注释,默认为保留,为了达到更好的压缩效果,可以设置为false
          */
          comments: false
        },
        compress: {
          /*
           是否在UglifyJS删除没有用到的代码时输出警告信息,默认为输出,可以设置为false关闭这些作用
           不大的警告
          */
          warnings: false,

          /*
           是否删除代码中所有的console语句,默认为不删除,开启后,会删除所有的console语句
          */
          drop_console: true,

          /*
           是否内嵌虽然已经定义了,但是只用到一次的变量,比如将 var x = 1; y = x, 转换成 y = 5, 默认为不
           转换,为了达到更好的压缩效果,可以设置为false
          */
          collapse_vars: true,

          /*
           是否提取出现了多次但是没有定义成变量去引用的静态值,比如将 x = 'xxx'; y = 'xxx'  转换成
           var a = 'xxxx'; x = a; y = a; 默认为不转换,为了达到更好的压缩效果,可以设置为false
          */
          reduce_vars: true
        }
      }
    }),
  ]
}
复制代码

test: 使用正则去匹配哪些文件需要被 ParallelUglifyPlugin 压缩,默认是 /.js$/.

include: 使用正则去包含被 ParallelUglifyPlugin 压缩的文件,默认为 [].

exclude: 使用正则去不包含被 ParallelUglifyPlugin 压缩的文件,默认为 [].

cacheDir: 缓存压缩后的结果,下次遇到一样的输入时直接从缓存中获取压缩后的结果并返回,cacheDir 用于配置缓存存放的目录路径。默认不会缓存,想开启缓存请设置一个目录路径。

workerCount:开启几个子进程去并发的执行压缩。默认是当前运行电脑的 CPU 核数减去1

sourceMap:是否为压缩后的代码生成对应的Source Map, 默认不生成,开启后耗时会大大增加,一般不会将压缩后的代码的 sourceMap发送给网站用户的浏览器。

uglifyJS:用于压缩 ES5 代码时的配置,Object 类型,直接透传给 UglifyJS 的参数。

uglifyES:用于压缩 ES6 代码时的配置,Object 类型,直接透传给 UglifyES 的参数。

最终的配置(根据实际情况取舍),项目中的打包速度提升了将近20s(54786ms),多次测试相差不大,可以说很可观了

new ParallelUglifyPlugin({
    output:{
      beautify: false,
      comments: false
    },
    compress:{
      warnings: false,
      drop_console: true,
      collapse_vars: true,
      reduce_vars: true
    },
    test: /.js$/g,
    include: [],
    exclude: [],
    cacheDir: '',
    workerCount: '',
    sourceMap: false
 })
复制代码

webpack可以说是前端工程化不可或缺的一部分了,目前来看版本更新算比较快的,如何学习新的知识,面对新的问题,怕是避免不了的了,前端路漫漫,上下而求索,就这样吧

猜你喜欢

转载自blog.csdn.net/weixin_34088583/article/details/91368481