使用esbuild提升webpack5的性能
项目冷启动
一般情况下,我们对一个jsx?
文件的解析loader
是这么配置:
{
test: /\.[jt]sx?$/,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-react', '@babel/preset-typescript']
}
}
]
}
现有项目在做了dll
优化的情况下,开发冷启动时间在2s+
甚至3s+
这个时间:
webpack 5.65.0 compiled successfully in 2419 ms
热更新时间基本在100ms
左右:
./src/app.jsx 192 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 174 ms
./src/app.jsx 192 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 156 ms
./src/app.jsx 192 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 62 ms
./src/app.jsx 192 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 90 ms
使用esbuild-loader
替换一下:
{
test: /\.[jt]sx?$/,
use: [
{
loader: 'esbuild-loader',
options: {
loader: 'tsx'
}
}
]
},
冷启动时间有了比较显著的提升,可以控制在2s
以内:
webpack 5.65.0 compiled successfully in 1672 ms
热更新时间基本在100ms
以内:
./src/app.jsx 168 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 137 ms # 啪~!
./src/app.jsx 234 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 59 ms
./src/app.jsx 234 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 58 ms
./src/app.jsx 192 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 92 ms
...
……反正看着是能快点……那webpack
配置还简单了呢,不用额外装preset
了啊。
所以
主要是冷启动时间提升。但我这个项目是个demo而已,不知道在大项目里是不是能有更好的表现。
编译压缩
以前常用的uglifyjs-webpack-plugin
在webpack5
项目里是没办法安装的,报依赖错误,要求降级到webpack^4
。
而且只要配置上--mode=production
,webpack
自然会压缩代码,所以这个uglify-js
貌似并没有那么重要了。
根据以前的经验,使用uglify-js
会比webpack
的压缩输出还要再小一点,然后找到了一个新的压缩插件:terser-webpack-plugin
,url: terser-webpack-plugin。
在这个插件中,内置了四个压缩引擎,分别是:terser
uglify-js
swc
esbuild
;其中后面三个,还需要额外安装依赖unlify-js
@swc/core
和esbuild
。找了一个现成的项目,分别进行了压缩测试,结果还是非常值得玩味的。
先上webpack
的配置文件,这是上面那个项目的dll
的输出配置:
const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { DllPlugin } = require('webpack')
const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
entry: {
react: ['react', 'react-dom'],
vue: ['vue'],
},
output: {
path: path.resolve(__dirname, 'dll'),
filename: '[name].dll.js',
library: '[name]_dll',
},
mode: 'production',
plugins: [
new CleanWebpackPlugin(),
new DllPlugin({
path: path.resolve(__dirname, './dll/manifest_[name].json'),
name: '[name]_dll',
context: __dirname,
}),
],
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
test: /\.js(\?.*)?$/i,
// minify: TerserPlugin.terserMinify,
// minify: TerserPlugin.uglifyJsMinify,
// minify: TerserPlugin.swcMinify,
// minify: TerserPlugin.esbuildMinify,
terserOptions: {},
}),
],
},
}
使用webpack原生压缩
这种情况,是在配置中把optimization
节点完全删掉了,主要结果为:
asset react.dll.js 127 KiB [emitted] [minimized] (name: react) 1 related asset
asset vue.dll.js 64.2 KiB [emitted] [minimized] (name: vue) 1 related asset
webpack 5.65.0 compiled successfully in 5264 ms
使用 terserMinify
asset react.dll.js 127 KiB [emitted] [minimized] (name: react) 1 related asset
asset vue.dll.js 64.5 KiB [emitted] [minimized] (name: vue) 1 related asset
webpack 5.65.0 compiled successfully in 3895 ms
使用 uglifyJsMinify
asset react.dll.js 126 KiB [emitted] [minimized] (name: react) 1 related asset
asset vue.dll.js 63.5 KiB [emitted] [minimized] (name: vue) 1 related asset
webpack 5.65.0 compiled successfully in 5377 ms
使用 swcMinify
asset react.dll.js 127 KiB [emitted] [minimized] (name: react)
asset vue.dll.js 64.1 KiB [emitted] [minimized] (name: vue)
webpack 5.65.0 compiled successfully in 1030 ms
使用 esbuildMinify
asset react.dll.js 129 KiB [emitted] [minimized] (name: react)
asset vue.dll.js 68.2 KiB [emitted] [minimized] (name: vue)
webpack 5.65.0 compiled successfully in 753 ms
数据汇总
引擎 | react体积(KiB) | vue体积(KiB) | 耗时(ms) |
---|---|---|---|
原生 | 127 | 64.2 | 5264 |
terser | 127 | 64.5 | 3895 |
uglify-js | 126 | 63.5 | 5377 |
swc | 127 | 64.1 | 1030 |
esbuild | 129 | 68.2 | 753 |
可以看到,uglify-js
和esbuild
分别是体积最优解和时间最优解。
PS: swc和esbuild分别是基于rust和golang的js代码转译工具。
以上。
转载自:https://juejin.cn/post/7049638461229236238