
背景
上一篇文章我們分析了:為什麼 esbuild 這麼快
還有資料對比:
可以明顯看到:
esbuild
一騎絕塵, 以絕對優勢領先。
看看最下面, 赫然是我們最熟悉的
webpack
。
那麼,
webpack 的建構為什麼慢呢?到底慢在哪呢 ?
下面是我的一些思考,分享給大家,希望對大家有所幫助。
正文
首先我們先看一下 webpack 建構的大緻流程:
webpack build flow
流程走的比較長。
那麼,整個流程的
性能瓶頸
在哪裡呢?
我認為主要是在以下兩個階段:
-
代碼建構
-
代碼壓縮
https://www.quora.com/What-is-Webpack-and-babel-loader
我們分别來看。
1. 代碼建構
代碼建構階段, 需要做的一個很重要的事情是
子產品依賴分析
, 生成
Module Graph
。
這部分有十分複雜的流程。
webpack build graph
https://medium.com/webpack/the-chunk-graph-algorithm-week-26-29-7c88aa5e4b4e
這部分非常複雜,也比較耗時。
為此 webpack 也設計了對應的的
算法
去優化這部分,感興趣的可以去研究一下。
這部分的詳細解析,有個視訊講的不錯,感興趣的可以去看一下:
https://youtu.be/Lzh8A0p3z8g
說回建構。
現代浏覽器對
esm
支援的越來越好,子產品依賴分析的工作,浏覽器就能完成。
而且, 浏覽器的很多包分析工具是用
C/C++
寫的, 顯然是要比
webpack
使用
js
去分析整個
依賴圖譜
更具優勢,速度上也是要快很多的。
2. 代碼壓縮
目前最成熟的 js 壓縮工具是
UglifyJS
。
它會分析 js 的
代碼文法樹
, 了解代碼含義,進而能做到諸如: 去掉無效代碼,去掉日志輸出代碼,縮短變量名等優化。
webpack 使用
壓縮插件
來完成這部分工作。
其中:
webpack
使用的
terser
, 是用
js
寫的, 源自于最早的
uglyfy.js
, 功能很豐富, 但是速度非常非常慢。
這點, 也是 webpack 速度慢的原因之一。
不過在代碼壓縮方面,
vite
選擇的也是
Terser
。
對此,文檔中有相關描述:
- build.minify:
- 類型:boolean | 'terser' | 'esbuild'
- 預設:'terser'
設定為
false
可以禁用最小化混淆,或是用來指定使用哪種混淆器。
預設為
Terser
。
雖然
Terser
相對
較慢
,但大多數情況下建構後的
檔案體積更小
。
ESbuild 最小化混淆
更快
, 但建構後的檔案
相對更大
。
更多資訊可以參考:https://cn.vitejs.dev/config/#build-minify
另外,如果你有留意, 就會發現一個現象:
- Esbuild, 使用
寫的。GO
- SWC, 是用
寫的。Rust
都不是用
js
寫的。
未來前端的編譯工具,大概也會往這個方向走, 要麼用
Go
寫, 要麼用
Rust
寫,而不是把這種能形成
性能瓶頸
的東西用
js
來實作。
還有一點需要提一下。
在文章開頭的圖中, 看起來 webpack5 的速度比 webpack4 要慢:
但這
不代表
webpack 5 不好,大家不要誤會啊。
webpack 5
裡面 做了
大量的優化
,
甩掉了不少曆史包袱
。
有一些
新特性
還有
非常有用
的, 比如:
-
Module Federation
-
Real Content Hash
不難想到,
webpack
團隊還是做出了很多努力的, ❤️ 。
總結
這篇文章, 是半夜突然有了思路, 花了兩個小時寫出來。
分享給大家,希望對大家有所啟發, 謝謝。