Webpack+ESbuild实战记录,编译速度提升一倍
摘要
由于团队内项目体积很大,webpack
的打包速度非常之慢,因此最近在探索相关的优化方案。项目是使用create-react-app
创建的,迁移到vite
成本太高,因此采用了部分转换为esbuild-loader
的方案,编译速度也有近一倍的提升。
分析工具
在优化之前,我们需要使用一些量化分析的工具,使用它们来帮助我们前后对比,确定优化指标
speed-measure-webpack-plugin
插件可以在打包后,于命令行输出各个插件和loader
的耗时情况,我们可以看出哪些loader
和plugin
耗时比较久,然后对其进行优化
speed-measure-webpack-plugin官方文档的使用方式如下,但笔者使用这种写法时,出现严重拖慢打包速度的现象
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
module.exports = smp.wrap({
// ...webpackConfig
})
改为如下写法后恢复正常
const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
module.exports = smp.wrap({
plugins: [
// ...plugins
new SpeedMeasurePlugin()
]
})
反向优化的多进程打包
happypack
和thread-loader
-
happypack
已经很多年没有维护了,核心原理是启用多进程,多个loader
并行处理文件,happypack
开发人员建议,如果使用webpack4
及以上更推荐使用thread-loader
,thread-loader
做的事情和happypack
一样 -
thread-loader
是webpack
官方推荐的,原理是将loader放在单独的一个worker
进程内处理,但实测下来babel-loader
前放置thread-loader
后的速度更慢了,原因如下
thread-loader
实现是node
的child_process
即子进程- 系统开一个子进程的开销比新开一个线程
worker_threads
大的多- 进程间通信也会消耗大量时间
使用 esbuild-loader
替换 babel-loader和ts-loader
esbuild
的底层原理是用go
生成的二进制文件处理js
或ts
,速度比babel
更快。如果没有使用babel
插件,可以在webpack
中直接用esbuild-loader
替换babel
module.exports = {
module: {
rules: [
- {
- test: /\.js$/,
- use: 'babel-loader'
- },
- {
- test: /\.tsx?$/,
- use: 'ts-loader'
- },
+ {
+ // Match js, jsx, ts & tsx files
+ test: /\.[jt]sx?$/,
+ loader: 'esbuild-loader',
+ options: {
+ // JavaScript version to compile to
+ target: 'es2015',
+ loader: 'jsx'
+ }
+ },
...
],
},
}
替换后,我们使用npm run serve
实验一下,发现首次编译速度提升了一倍左右
二次编译的情况下,由于二者都有缓存,编译速度都有提升,不使用esbuild-loader
时约42s,而使用esbuild-loader
后达到了接近vite
的秒开级
替换 TerserPlugin 和 CssMinimizerPlugin
esbuild
也可以进行代码压缩
+ const { EsbuildPlugin } = require('esbuild-loader')
module.exports = {
optimization: {
minimizer: [
- new TerserPlugin({
- ...
- }),
- new CssMinimizerPlugin({
- ...
- }),
+ optimization: {
+ minimizer: [
+ new EsbuildPlugin({
+ target: 'es2015',
+ // 如果提取CSS并将其作为单独的文件发出
+ css: true
+ })
+ ]
+ },
...
],
},
}
替换后,运行npm run build
打包,打包时间从67.5s减少到36s,依然是接近一倍的提升
但是观察打包产物,发现体积增大了约2%。通常情况下,为了节省构建时间让用户包增大是不能接受的,需要做出取舍。因此我们可以在生产环境构建压缩用terser
节约空间,开发环境用esbuild
节约时间。
参考文献
转载自:https://juejin.cn/post/7216617762667937852