分享一个高性能的webpack uglify plugin
发布于 5 年前 作者 keller35 9302 次浏览 来自 分享

fast-uglifyjs-plugin

介绍

这里要介绍的是我们开发的一个webpack plugin,用于替换webpack内置的UglifyJsPlugin,加快uglify的效率。

在使用webpack的过程中,我们发现uglify的阶段占据一次打包任务中大部分的时间。

于是我们在webpack内置的UglifyJsPlugin的基础上进行改造,增加了基于多进程的并行uglify和利用缓存实现的按需uglify,最终效率提高非常明显。最近因为内部转为使用webpack 2,我们也实现了对webpack 2的兼容。

性能

插件 耗时
webpack.optimize.UglifyJsPlugin 7.4 min
FastUglifyJsPlugin without cache 4.45 min
FastUglifyJsPlugin with cache 36 s

使用

使用方法跟内置的UglifyJsPlugin基本相同,关于如何使用,请参考文档

实现

下面介绍一下实现过程:

在webpack内部对象compilation的生命周期optimize-chunk-assets中,可以对经过当前plugin的chunk进行处理。

chunk在webpack文档中的解释是:

Each chunk manages the composition of a final rendered assets

通俗说就是表示最终输出的对象,而chunk中的属性chunk.files表示了最终输出的文件,所以对chunk.files进行uglify就是webpack内置的UglifyJsPlugin的实现原理。

在这个基础上,我们对uglify的过程进行了改造,改造的内容如下:
  1. 开启多个worker进程,将对chunk.files的uglify任务分发到多个worker进程中进行,完成后通知主进程进行统一处理。 这样并行的执行uglify,相比于串行,当任务量大的时候,效率提升是很明显的。 关于worker进程的实现,可以查看代码worker.js

  2. 因为并不是每次执行webpack任务,所有文件都需要重新uglify,只对修改的文件进行uglify将会对整体效率有巨大的提高。 所以我们增加了文件缓存的功能,webpack每次执行都会缓存上一次uglify的结果,缓存的内容包含了文件名的hash和文件内容的hash,这样在下次uglify时,通过对比hash,如果可以在缓存中找到命中的文件,则跳过uglify直接使用缓存内容。 关于缓存的实现,可以查看代码UglifyCache.js

使用过程中有什么问题,欢迎issue和pr。

1 回复

第一次打包因为写缓存,消耗的时间本比webpack 的UglifyJsPlugin 都高

回到顶部