成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

探討Esbuild 為什么那么快

開發 前端
大多數前端打包工具都是基于 JavaScript 實現的,而 Esbuild 則選擇使用 Go 語言編寫,兩種語言各自有其擅長的場景,但是在資源打包這種 CPU 密集場景下,Go 更具性能優勢,差距有多大呢?

[[404663]]

Esbuild 是什么

Esbuild 是一個非常新的模塊打包工具,它提供了與 Webpack、Rollup、Parcel 等工具「相似」的資源打包能力,卻有著高的離譜的性能優勢:

從上到下,耗時逐步上升達到數百倍的差異,這個巨大的性能優勢使得 Esbuild 在一眾基于 Node 的構建工具中迅速躥紅,特別是 Vite 2.0 宣布使用 Esbuild 預構建依賴后,前端社區關于它的討論熱度迅速上升。

那么問題來了,這是怎么做到的?我翻閱了很多資料后,總結了一些關鍵因素:

下面展開一一細講。

為什么快

語言優勢

大多數前端打包工具都是基于 JavaScript 實現的,而 Esbuild 則選擇使用 Go 語言編寫,兩種語言各自有其擅長的場景,但是在資源打包這種 CPU 密集場景下,Go 更具性能優勢,差距有多大呢?比如計算 50 次斐波那契數列,JS 版本:

  1. function fibonacci(num) { 
  2.     if (num < 2) { 
  3.         return 1 
  4.     } 
  5.     return fibonacci(num - 1) + fibonacci(num - 2) 
  6.  
  7. (() => { 
  8.     let cursor = 0; 
  9.     while (cursor < 50) { 
  10.         fibonacci(cursor++) 
  11.     } 
  12. })() 

 

Go 版本:

  1. package main 
  2.  
  3. func fibonacci(num intint
  4.     if num<2{ 
  5.         return 1 
  6.     } 
  7.      
  8.     return fibonacci(num-1) + fibonacci(num-2) 
  9.  
  10. func main(){ 
  11.     for i := 0; i<50; i++{ 
  12.         fibonacci(i) 
  13.     } 

 

JavaScript 版本執行耗時大約為 「332.58s」,Go 版本執行耗時大約為 「147.08s」,兩者相差約 「1.25」 倍,這個簡單實驗并不能精確定量兩種語言的性能差別,但感官上還是能明顯感知 Go 語言在 CPU 密集場景下會有更好的性能表現。

歸根到底,雖然現代 JS 引擎與10年前相比有巨大的提升,但 JavaScript 本質上依然是一門解釋型語言,JavaScript 程序每次執行都需要先由解釋器一邊將源碼翻譯成機器語言,一邊調度執行;而 Go 是一種編譯型語言,在編譯階段就已經將源碼轉譯為機器碼,啟動時只需要直接執行這些機器碼即可。

這種語言層面的差異在打包場景下特別突出,說的夸張一點,JavaScript 運行時還在解釋代碼的時候,Esbuild 已經在解析用戶代碼;JavaScript 運行時解釋完代碼剛準備啟動的時候,Esbuild 可能已經打包完畢,退出進程了!

圖片

所以在編譯運行層面,Go 前置了源碼編譯過程,相對 JavaScript 邊解釋邊運行的方式有更高的執行性能。

多線程優勢

Go 天生具有多線程運行能力,而 JavaScript 本質上是一門單線程語言,直到引入 WebWorker 規范之后才有可能在瀏覽器、Node 中實現多線程操作。

我曾經研讀過 Rollup、Webpack 的代碼,就我熟知的范圍內兩者均未使用 WebWorker 提供的多線程能力。反觀 Esbuild,它最核心的賣點就是性能,它的實現算法經過非常精心的設計,盡可能飽和地使用各個 CPU 核,特別是打包過程的解析、代碼生成階段已經實現完全并行處理。

圖片
圖片

除了 CPU 指令運行層面的并行外,Go 語言多個線程之間還能共享相同的內存空間,而 JavaScript 的每個線程都有自己獨有的內存堆。這意味著 Go 中多個處理單元,例如解析資源 A 的線程,可以直接讀取資源 B 線程的運行結果,而在 JavaScript 中相同的操作需要調用通訊接口 woker.postMessage 在線程間復制數據。

所以在運行時層面,Go 擁有天然的多線程能力,更高效的內存使用率,也就意味著更高的運行性能。

節制

對,沒錯,節制!

Esbuild 并不是另一個 Webpack,它僅僅提供了構建一個現代 Web 應用所需的最小功能集合,未來也不會大規模加入我們業已熟悉的各類構建特性。最新版本 Esbuild 的主要功能特性有:

  • 支持 js、ts、jsx、css、json、文本、圖片等資源
  • 增量更新
  • Sourcemap
  • 開發服務器支持
  • 代碼壓縮
  • Code split
  • Tree shaking
  • 插件支持

可以看到,這份列表中支持的資源類型、工程化特性非常少,甚至并不足以支撐一個大型項目的開發需求。在這之外,官網明確聲明未來沒有計劃支持如下特性:

  • Elm, Svelte, Vue, Angular 等代碼文件格式
  • Ts 類型檢查
  • AST 相關操作 API
  • Hot Module Replace
  • Module Federation

而且,Esbuild 所設計的插件系統也無意覆蓋以上這些場景,這就意味著第三方開發者無法通過「插件」這種無侵入的方式實現上述功能,emmm,可以預見未來可能會出現很多魔改版本。

Esbuild 只解決一部分問題,所以它的架構復雜度相對較小,相對地編碼復雜度也會小很多,相對于 Webpack、Rollup 等大一統的工具,也自然更容易把性能做到極致。節制的功能設計還能帶來另外一個好處:完全為性能定制的各種附加工具。

定制

回顧一下,在 Webpack、Rollup 這類工具中,我們不得不使用很多額外的第三方插件來解決各種工程需求,比如:

  • 使用 babel 實現 ES 版本轉譯
  • 使用 eslint 實現代碼檢查
  • 使用 TSC 實現 ts 代碼轉譯與代碼檢查
  • 使用 less、stylus、sass 等 css 預處理工具

我們已經完全習慣了這種方式,甚至覺得事情就應該是這樣的,大多數人可能根本沒有意識到事情可以有另一種解決方案。Esbuild 起了個頭,選擇完全!完全重寫整套編譯流程所需要用到的所有工具!這意味著它需要重寫 js、ts、jsx、json 等資源文件的加載、解析、鏈接、代碼生成邏輯。

開發成本很高,而且可能被動陷入封閉的風險,但收益也是巨大的,它可以一路貫徹原則,以性能為最高優先級定制編譯的各個階段,比如說:

  • 重寫 ts 轉譯工具,完全拋棄 ts 類型檢查,只做代碼轉換
  • 大多數打包工具把詞法分析、語法分析、符號聲明等步驟拆解為多個高內聚低耦合的處理單元,各個模塊職責分明,可讀性、可維護性較高。而 Esbuild 則堅持性能第一原則,不惜采用反直覺的設計模式,將多個處理算法混合在一起降低編譯過程數據流轉所帶來的性能損耗
  • 一致的數據結構,以及衍生出的高效緩存策略,下一節細講

這種深度定制一方面降低了設計成本,能夠保持編譯鏈條的架構一致性;一方面能夠貫徹性能第一的原則,確保每個環節以及環節之間交互性能的最優。雖然伴隨著功能、可讀性、可維護性層面的的犧牲,但在編譯性能方面幾乎做到了極致。

結構一致性

上一節我們講到 Esbuild 選擇重寫包括 js、ts、jsx、css 等語言在內的轉譯工具,所以它更能保證源代碼在編譯步驟之間的結構一致性,比如在 Webpack 中使用 babel-loader 處理 JavaScript 代碼時,可能需要經過多次數據轉換:

  • Webpack 讀入源碼,此時為字符串形式
  • Babel 解析源碼,轉換為 AST 形式
  • Babel 將源碼 AST 轉換為低版本 AST
  • Babel 將低版本 AST generate 為低版本源碼,字符串形式
  • Webpack 解析低版本源碼
  • Webpack 將多個模塊打包成最終產物

源碼需要經歷 string => AST => AST => string => AST => string ,在字符串與 AST 之間反復橫跳。

而 Esbuild 重寫大多數轉譯工具之后,能夠在多個編譯階段共用相似的 AST 結構,盡可能減少字符串到 AST 的結構轉換,提升內存使用效率。

總結

單純從編譯性能的維度看,Esbuild 確實完勝世面上所有打包框架,差距甚至能在百倍之大:

但這是有代價的,刨除語言層面的天然優勢外,在功能層面它直接放棄對 less、stylus、sass、vue、angular 等資源的支持,放棄 MF、HMR、TS 類型檢查等功能,正如作者所說:

❝This will involve saying "no" to requests for adding major features to esbuild itself. I don't think esbuild should become an all-in-one solution for all frontend needs!❞

在我看來,Esbuild 當下與未來都不能替代 Webpack,它不適合直接用于生產環境,而更適合作為一種偏底層的模塊打包工具,需要在它的基礎上二次封裝,擴展出一套既兼顧性能又有完備工程化能力的工具鏈,例如 Snowpack, Vite, SvelteKit, Remix Run 等。

總的來說,Esbuild 提供了一種新的設計思路,值得學習了解,但對大多數業務場景還不適合直接投入生產使用。

 

責任編輯:姜華 來源: Tecvan
相關推薦

2021-05-27 20:56:51

esbuild 工具JavaScript

2023-06-08 18:25:40

Doris場景查詢

2023-10-15 12:23:10

單線程Redis

2020-07-29 08:06:30

Kafka MQ消息

2019-10-18 14:54:04

Kafka寫入磁盤

2019-05-10 09:47:33

2022-02-24 07:56:42

開發Viteesbuild

2020-02-27 21:03:30

調度器架構效率

2020-08-03 07:50:56

存儲對象存儲

2020-02-27 15:44:41

Nginx服務器反向代理

2024-02-26 21:15:20

Kafka緩存參數

2022-01-24 14:42:03

手機技術廠商

2024-04-03 09:23:31

ES索引分析器

2017-03-25 21:32:40

Python編碼

2020-03-30 15:05:46

Kafka消息數據

2019-10-18 09:40:19

程序員固態硬盤Linux

2023-11-20 17:38:07

Djangoagtailadmin

2022-02-21 10:06:14

自動駕駛汽車智能

2017-01-21 14:57:43

Linuxsystemd

2025-05-27 02:20:00

PG數據庫DBA
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本韩国欧美在线观看 | 一区二区精品电影 | 综合一区二区三区 | 亚洲福利在线观看 | 91久久久精品国产一区二区蜜臀 | 精品一二区 | 欧美午夜一区二区三区免费大片 | 久操av在线 | 中国av在线免费观看 | www一级片| 一二区成人影院电影网 | 日本欧美国产在线 | 国产欧美日韩综合精品一区二区 | 日本精品视频 | 日韩国产中文字幕 | 超级黄色一级片 | 日日拍夜夜 | 国产日韩欧美一区二区 | 日日夜夜精品 | 五月婷婷在线播放 | 亚洲国产中文在线 | 国产91精品久久久久久久网曝门 | 成人在线播放网站 | 日本免费视频 | 久热国产精品视频 | 99久久日韩精品免费热麻豆美女 | 亚洲国产精品久久久久秋霞不卡 | 国产高清视频在线观看 | 国产亚洲一区二区三区 | 亚洲精品一区二三区不卡 | 蜜桃五月天 | 免费看啪啪网站 | 伊人久久综合 | 91精品一区 | 精品久久av | 国产三区四区 | 日韩不卡视频在线观看 | 午夜在线小视频 | 1区2区视频 | dy天堂| a成人|