扣丁書屋

用 esbuild 讓你的構建壓縮性能翻倍

https://zhuanlan.zhihu.com/p/139219361 支付寶@陳成

不知大家是否有遇到這個問題,

<--- Last few GCs --->

[59757:0x103000000]    32063 ms: Mark-sweep 1393.5 (1477.7) -> 1393.5 (1477.7) MB, 109.0 / 0.0 ms  allocation failure GC in old space requested

<--- JS stacktrace --->

==== JS stack trace =========================================

Security context: 0x24d9482a5ec1 <JSObject>
    ...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: node::Abort() [/Users/xxx/.nvm/versions/node/v10.13.1/bin/node]
 2: ...

或者在 92% 的進度里卡很久,

● Webpack █████████████████████████ chunk asset optimization (92%) TerserPlugin

隨著產物越來越大,編譯上線和 CI 的時間都越來越長,而其中 1/3 及更多的時間則是在做壓縮的部分。OOM 的問題也通常來源于壓縮,我們推出的 UglifyCache 和 autoExternal 方案其實大部分也是在解決產物大了之后壓縮慢從而可能導致 OOM的問題。

如何解決壓縮慢和占內存的問題,一直很令人頭疼。

esbuild

An extremely fast JavaScript bundler and minifier.

特點就是快,

為啥快?作者給了幾個原因,但其中最主要的應該是用 go 寫,然后編譯為 Native 代碼。然后 npm 安裝時動態去下對應平臺的二進制包,支持 mac、linux 和 windows,比如 esbuild-darwin-64。

相同思路的還有 es-module-lexer、swc 等,都是用編譯成 Native 代碼的方式進行提速。

esbuild 有兩個功能,bundler 和 minifier。bundler 的功能和 babel 以及 webpack 相比肯定差很多,直接上風險太大;而 minifier 倒是可以試試,在 webpack 和 babel 產物的基礎上做一次壓縮,坑應該相對較少。

我先直接用 esbuild 壓一個 5M 多的文件到 1.5M,效果明顯。

$ esbuild --minify --outfile=esbuild-minify-test.js dist-uncompressed/umi.b9ab1e60.js
Wrote to esbuild-minify-test.js (1.5mb)
Done in 294ms

esbuild-webpack-plugin

為進一步驗證效果,寫了 webpack 插件和 Umi 插件。以依賴了全量 antd 和 bizcharts 的項目為例,在禁用 Babel 緩存和 Terser 緩存的基礎上進行了測試。

大家感興趣的可以自行 clone 倉庫,在 yarn install 后分別執行,

// 用默認的 terser 壓縮
$ yarn build:example

// 用 esbuild 壓縮
$ yarn build:example:esbuild

// 不壓縮
$ yarn build:example:nocompress

跑的結果,

結論如下:

  1. 編譯時間減少近 1/3,產物越大越明顯
  2. Gzip 前的尺寸變化不明顯,Gzip 后的尺寸略有增加
  3. 內存消耗降低很多,基本可忽略(拿 process.memoryUsage().heapUsed 的值,因為有子進程,可能不準)

未來

不管是 Bundled 還是 Unbundled,其中肯定會有一些重計算的部分,這些應該是會轉向 Native 代碼實現,比如壓縮、Babel 編譯、TS 編譯、模塊分析等。

至于應用場景,一開始步子應該邁不大,可以先局部嘗試起來,比如壓縮、組件庫開發時的 TS 編譯等。Umi 會在 3.2 內置這種壓縮方式,通過 minifier: { type: 'esbuild' } 提供,打 beta 使用警告??。

在 Umi 中使用

通過插件 @umijs/plugin-esbuild 一鍵開啟。

先安裝依賴,

$ yarn add @umijs/plugin-esbuild

然后配置開啟,

export default {
  esbuild: {},
};

最多閱讀

為Electron程序添加運行時日志 3年以前  |  14868次閱讀
Node.js下通過配置host訪問URL 3年以前  |  4765次閱讀
js動態創建類和實例化 3年以前  |  3902次閱讀
wordpress標簽頁的制作 3年以前  |  3739次閱讀
初探 React 組件 3年以前  |  3712次閱讀
用 esbuild 讓你的構建壓縮性能翻倍 2年以前  |  3701次閱讀
500行PHP代碼搞定富文本安全過濾 3年以前  |  3606次閱讀
10 種跨域解決方案(附終極方案) 2年以前  |  3508次閱讀
22個HTML5的初級技巧 3年以前  |  3480次閱讀
MBTI免費在線測試 3年以前  |  3428次閱讀
使用 SRI 增強 localStorage 代碼安全 3年以前  |  3357次閱讀
淺談瀏覽器的原生拖拽事件 3年以前  |  3352次閱讀
CSS清除浮動 3年以前  |  3348次閱讀
第三版主題上線 3年以前  |  3285次閱讀
利用服務器返回header來傳輸數據 3年以前  |  3256次閱讀

手機掃碼閱讀
18禁止午夜福利体验区,人与动人物xxxx毛片人与狍,色男人窝网站聚色窝
<蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>