縮小 JavaScript 規模:掌握 Bundler 優化
介紹
在過去的 15 年裡,JavaScript 生態系統迅速擴展,引入了無數工具使開發變得更加容易。但這些工具是有代價的:增加捆綁包的大小。事實上,HTTP Archive 的數據顯示,每頁平均傳輸的 JavaScript 量已從 2010 年的 90 KB 激增至 2024 年的 650 KB(來源)。
儘管壓縮技術的採用率不斷提高並且取得了進步,但這一趨勢並沒有顯示出放緩的跡象。隨著我們不斷添加功能,挑戰仍然存在:我們如何減少 JavaScript 的數量?
奇怪的是,解決方案既簡單又困難。最簡單的部分是專案層級的調整,可以快速取得成果。困難的部分是產生持久的影響,這需要社區範圍內的改變來改善捆綁器、庫和工具。
本文著重於您的專案的可行改進,涵蓋:
- 捆綁器:最佳化建置工具以減少輸出大小。
- 函式庫:明智地選擇和使用外部相依性。
- 您的專案:縮小捆綁包的實用步驟。
未來的文章將討論我們可以做出的生態系統範圍內的改進,但現在,讓我們解決這些因素如何導致捆綁包膨脹 - 以及如何管理它們。
為什麼優化 JavaScript 很重要
JavaScript 是現代網路互動背後的引擎,但它不是免費的。 JavaScript 是瀏覽器必須處理的計算成本最高的資源。它通常是決定頁面感覺快還是慢的瓶頸,因為臃腫的套件會阻止渲染並降低整體效能。
JavaScript 套件越大,載入、解析、編譯和執行所需的時間就越長。這會延遲其他一切 - 例如顯示內容或讓使用者與頁面互動。對於使用具有光纖連接的高階筆記型電腦的人來說,這可能是一個小煩惱。但對於使用低功率手機或不穩定網路的人來說,這可能是完全留在或離開您的網站的區別。
減少 JavaScript 套件大小的第一步是 Tree Shaking(或「死程式碼消除」),大多數的捆綁器都是開箱即用。但所有捆綁商都是平等的嗎?
捆綁者
JavaScript 中的捆綁已經取得了長足的進步——從手動串聯和任務運行器到複雜的捆綁器。如今,捆綁器效能是一個關鍵焦點,開發人員優先考慮更快的建置。然而,建造速度並不是一切。同樣重要的是它們產生的捆綁包的大小,因為較小的捆綁包意味著用戶的載入時間更快。
為了尋求更好的效能,我們已經從使用 JavaScript 編寫捆綁器轉向 Rust 和 Go 等語言。此切換需要從頭開始編寫它們,因此舊捆綁器中存在的每個功能和最佳化都必須重新實現。從長遠來看,這可能會得到回報。然而,從短期來看,這意味著它們缺少 JavaScript 捆綁器多年來開發的一些功能,例如良好的 tree shake。這正是可以幫助我們最小化捆綁包大小的功能。
基準
當然,空談是廉價的,所以讓我們看看數字,好嗎?
讓我們比較八個流行的庫,並將它們與七個流行的捆綁器捆綁在一起。為了保持公平,我使用了:
- 節點 22.12.0
- 自我報告的建構時間
- 第三次運行計時,讓快取預熱,特別是像 Parcel 這樣的工具
- 刪除所有註解(包括許可證)的配置,因為捆綁程式以不同的方式處理它們
您可以查看基準設定儲存庫以取得確切的配置。
經過測試的捆綁器:
- esbuild (0.24.0)
- 包裹(2.13.2)
- 滾動(0.15.0-snapshot-993c4a1-20241205003858)
- 總結 (4.28.0)
- Rspack (1.1.5)
- Vite (6.0.3)
- webpack (5.97.1)
請注意,在撰寫本文時,Rolldown 仍處於 alpha 階段,因此它處於劣勢,隨著時間的推移,其結果可能會有所改善。
測試過的函式庫:
- chart.js
- ckeditor5
- d3
- 手工表
- 勒克森
- mobx
- tippy.js
- 佐德
這些函式庫的大小和功能各不相同 - 有些程式庫幾乎可以像獨立應用程式一樣運作。
建構速度
讓我們從建造速度開始,因為這是開發人員似乎非常關心的事情。將所有這些庫捆綁在一起時,esbuild 是獲勝者,其構建時間為 192 毫秒。與最慢的建置時間 7.23 秒相比,快了 37 倍以上。
根據這些結果,我們可以將捆綁器分為三類:
- 極快™:esbuild、Parcel、Rolldown(
- 更快:Rspack(2.2 秒)。
- 慢:Rollup、Vite、webpack(每個 5 秒)。
差異非常明顯。例如,Rolldown 和 Rspack 分別比舊版 Rollup 和 webpack 快 11.5 倍和 3.3 倍,同時保持理論上的向後相容性。切換到這些較新的捆綁器可以顯著提高大型專案的生產力。
輸出尺寸
就輸出大小而言,差異並不像建置時間那麼大,但它們仍然很重要。
匯總結果
將所有八個庫捆綁在一起時,Vite 是獲勝者,輸出大小為 2087 KiB。與最大輸出大小 2576 KiB 相比,輸出小了 23.5% 以上。
輸出大小的 23.5% 差異是巨大的:在較慢的 3G 連接下,最小的包可能需要大約 5.7 秒才能下載,而最大的包可能需要大約 7 秒。解析和執行時間也會隨著套件的大小而變化,因此現實世界的差異可能更加明顯。
根據這些結果,我們可以將捆綁器輸出再次分為三類:
- 最小:esbuild、Parcel、Rollup 和 Vite (~2085–2160KiB)。
- 好的:webpack (~2317KiB)。
- 大:Rolldown,Rspack (~2490–2580KiB)。
個別圖書館
聚合結果並不能描繪出全貌,因為您不太可能在專案中使用上面列出的所有函式庫。更有趣的是這些捆綁器如何處理各個庫。
對於像chart.js和mobx這樣的函式庫,捆綁器的選擇會大大影響輸出大小,差異達到70%。這凸顯了使用特定相依性測試捆綁程序的重要性。在大多數其他情況下,差異要小得多,約為 20-30%。
此外,雖然 webpack 總體排名居中,但在 8 個案例中,有 6 個案例表現最好。然而,由於在捆綁handsontable和chart.js時它的表現要差得多,所以它最終還是這樣。這意味著,根據您使用的庫,webpack 可能是一個不錯的選擇。
另一方面,我們有 Rolldown。它在 8 個案例中的 7 個案例中表現最差(請記住,它仍處於 alpha 狀態)。
Rspack 也是一個類似的故事。雖然它的性能比 Rolldown 更好,但它仍然產生了比其他捆綁器大得多的捆綁包。
如果您正在考慮遷移到較新的捆綁程序,使用您使用的庫進行測試,看看更快的構建速度是否不會以增加輸出大小為代價。
捆綁尺寸與輸出速度
如圖所示,較新的捆綁器速度更快,但可能會產生更大的捆綁包。從較舊的捆綁程式遷移時,不僅要比較建置時間,還要比較產生的捆綁包大小。您可能會發現自己用更快的構建來換取更大的捆綁包。
例如,在 Angular 從 webpack 切換到 esbuild 後,一些開發人員報告說,空的 Angular 應用程式的大小增加了約 20KB。這完美地突出了構建速度與捆綁包大小的權衡。
這並不是說您不應該關注構建速度,因為它對於開發人員的生產力和幸福感很重要。 CI 建置時間和合併程式碼所需的時間之間也存在相關性。
選擇捆綁器時,首先查看它提供的功能。然後目標是建造速度和包大小之間的平衡。選擇可以在您方便的時間內生產盡可能最小的捆綁包的捆綁包的捆綁商。
測試項目中的一些代表性庫。如果您的依賴項構成了程式碼庫的大部分,那麼您在這些基準測試中看到的差異可以很好地預測您的情況。
圖書館
我們清單中的下一個是外部函式庫,它們通常構成 JavaScript 套件的大部分。在我開發過的許多(如果不是大多數)應用程式中,它們佔據了捆綁包大小的大部分。這就是為什麼明智地選擇(和使用)它們如此重要。
黃金但舊
我們中的許多人都安裝了 lodash、axios 或 moment 等庫,只是為了使用單一功能 - 導致應用程式臃腫。這些庫很棒並且具有重要的歷史意義,但隨著它們變得越來越流行,更輕的替代品被創建,並且它們的一些功能被添加到語言本身中。
我們可以利用這一點。我可以列出這些庫的本機 API 或更新且更小的替代方案,但已經有很多文章對此進行了介紹。還有很多其他函式庫,不可能全部涵蓋。
這就是為什麼我只會給你一個一般性建議,讓你看看你使用的庫,看看是否可以刪除它們或用本機 API 或更小的替代品替換它們。您可能不需要 * 網站是一個很好的入門資源。
優化安裝路徑
預設情況下,大多數程式庫並未針對大小進行最佳化,但有些程式庫提供特殊的安裝路徑或部分建置。即使在我們測試的庫中,chart.js、handsontable 和 ckeditor5 也提供了一種透過僅包含您需要的部分來減小庫大小的方法。讓我們以 ckeditor5 為例。
預設安裝路徑導致捆綁包大小在 660 到 800 KiB 之間。但是,如果我們使用優化的安裝路徑,捆綁包大小會下降到 603-653 KiB,僅 Rolldown 產生的捆綁包大小約為 750 KiB。大小減少了 7% 到 23%,具體取決於捆綁程序。
重複的依賴項
另一件事要注意的是重複的依賴關係。這是 JavaScript 應用程式中一個令人驚訝的常見問題。例如,Bluesky 嵌入小工具有兩個版本的 zod 驗證庫。刪除重複項使套件大小減少了約 9%。
此問題通常不會發生,因為您拉取了同一庫的兩個不同版本,而是因為您和外部庫之一依賴同一庫,但版本不同。這通常可以透過更新您所依賴的程式庫來解決。
你的專案
考慮到所有這些,我們終於可以進入最後一塊拼圖 - 您的專案。您可以採取以下措施來縮小捆綁包並提高效能。
檢查您的捆綁包
第一步是可見性。如果不了解捆綁包中的內容,縮小捆綁包的大小就變成了一場猜謎遊戲。為此,您可以使用我創建的名為 Sonda 的捆綁分析器和視覺化工具。它適用於上述大多數捆綁程序(Parcel 除外),並準確顯示參與捆綁的各個文件的大小。
您可以先將其安裝到您的專案中並目視檢查捆綁包的各個部分。
一旦您充分了解了捆綁包內的內容並確定了可以優化的部分,您就可以單擊圖表圖塊來查看:
- 壓縮前後的檔案大小,
- 匯入所選文件的文件列表,
- 甚至檢查捆綁包中包含的部分原始碼。
Sonda 也會警告您重複的依賴項,以便您可以快速識別並修復問題的根源。
理想情況下,您不僅應該進行一次性檢查,還應該將持續監控設定為 CI 管道的一部分。追蹤一段時間內的變化,尤其是在大型專案中,可以幫助您防止小變化隨著時間的推移滾雪球般變成嚴重的膨脹。
刪除或優化外部程式庫
最快的程式碼是您不發送的程式碼。只要有可能:
- 刪除可以被原生 API 取代的函式庫。
- 將重量級庫替換為較小的替代品。
- 如果程式庫支持,請使用最佳化的安裝路徑。
使用程式碼分割
如果您無法刪除應用程式的某些部分,請嘗試程式碼分割。程式碼分割可讓您推遲載入應用程式的某些部分,直到需要它們為止,從而縮短初始載入時間。
使用動態 import() 按需載入模組。例如,如果在使用者點擊按鈕之前不需要某個特定功能,則會延遲載入該功能直到那一刻。
現代前端框架支援開箱即用的延遲加載,使將程式碼分割整合到您的工作流程中比以往更容易。
遵循最佳實踐
這是一般性建議,但值得重複。遵循最佳實踐,例如:
- 使用最新的目標,這樣代碼就不會被不必要的轉譯或填充。一些polyfills可以添加許多現代瀏覽器中根本不需要的程式碼,但許多環境仍然預設添加它們。您也可以設定提醒,每年更新目標。
- 定期更新依賴項,因為新版本通常會更小或更快。這還可以防止您必須處理安全漏洞或重複的依賴項。
- 評估您已經擁有或正在考慮新增的每個依賴項。如果您無法證明大小合理,請不要添加它或尋找更小的替代方案。
加入生態系績效 (e18e) 社區
如果您有興趣讓網路更快或只是學習新事物,您應該考慮加入生態系統效能社群。我們專注於三個主要領域:
- 清理 - 透過刪除冗餘依賴項或用現代替代方案替換它們來改進軟體包。
- 加速 — 提高廣泛使用的軟體包的效能。
- 升級-建構過時軟體包的現代替代品。
結論
我希望這篇文章說明您可以用更少的程式碼提供相同的功能。如果不加以管理,捆綁包大小可能會失控,但即使很小的更改也可以顯著提高效能。
從今天開始:分析您的套件、測試新工具或替換重量級庫。其影響會讓你大吃一驚。
我希望您喜歡這篇文章。如果您有任何問題或意見,或者如果您想了解有關特定主題的更多信息,請在下面的評論中告訴我。如果您想了解有關 JavaScript 性能、捆綁和 tree-shaking 主題的更多信息,您可以在此處關注我或在 BlueSky 上關注我並加入 e18e 社區。
以上是縮小 JavaScript 規模:掌握 Bundler 優化的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript不需要安裝,因為它已內置於現代瀏覽器中。你只需文本編輯器和瀏覽器即可開始使用。 1)在瀏覽器環境中,通過標籤嵌入HTML文件中運行。 2)在Node.js環境中,下載並安裝Node.js後,通過命令行運行JavaScript文件。
