[譯]webpack 4: Code Splitting和chunks切分優化

原文地址: webpack 4: Code Splitting, chunk graph and the splitChunks optimization
原文做者: Tobias Koppers
譯者: arzh
推薦理由: 從webpack3升級到webpack4所作的重要更改vue

webpack4chunk圖進行了一些重大改進,併爲chunk拆分添加了一個新的優化(這是對CommonsChunkPlugin的一種改進)node

讓咱們來看看舊版關係圖的一些缺點react

在舊圖中,chunks經過父子關係和chunks包含模塊來鏈接其餘的chunkswebpack

當一個chunk有多個父節點的話,咱們能夠認爲當這個chunk被加載的時候,至少有一個父節點已經被加載了.這個信息能夠被用來優化,例如,當一個chunk的模塊,在全部父節點均可用時,它能夠從chunk中被移除,由於它必定已經被成功加載了。web

在入口點或異步拆分點處引用chunk列表時,這些chunks會並行加載。緩存

這種類型的關係圖使得分離chunks變得十分困難,例如使用CommonsChunkPlugin會有這樣的問題,當你刪除一個或多個chunks模塊,並將它們放在一個新的chunk中,這個新的chunk須要被從新鏈接到關係圖中,可是如何鏈接呢?做爲舊的chunk的父級,仍是子級?CommonsChunkPlugin將其添加爲父級,但這在技術上是錯誤的,同時也會對其餘優化產生負面影響(父節點信息是不許確的)dom

新的chunk圖中引入了一個新對象: ChunkGroup,一個ChunkGroup包含多個chunk異步

在入口點或異步拆分點處引用單個ChunkGroup,這意味着全部被ChunkGroup包含的chunk都是並行加載的。一個chunk能夠被引用在多個ChunkGroup中(但不會被加載屢次)優化

如今就再也不使用父子關係來關聯chunk,而是經過ChunkGroup來進行關聯插件

如今chunks的分割能夠被理解了,新增長的chunks會被添加到全部包含原始chunkChunkGroups 中,這並不會對父層級關係產生負面影響。

如今這個問題被修復了,咱們就能夠開始更多的使用chunk分離了,咱們能夠任意拆分chunk而不用擔憂chunk圖會被破壞

CommonsChunkPlugin有許多的問題:

  1. 會下載一些咱們所不須要的代碼
  2. 在異步chunks下是低效率的
  3. 會比較難使用
  4. 實踐起來比較難以理解

因此新的插件誕生了:SplitChunksPlugin

它能經過heuristics自動識別應該被分塊的模塊,使用模塊重複計數和模塊類別(如node_modules),來分割chunks

這裏有一種二者的比喻。CommonsChunkPlugin就像:"建立一個chunk並將匹配minChunks的全部模塊移動到新塊中",SplitChunksPlugin就像:"這是heuristics,確保你知足他們"(Here are the heuristics, make sure you fullfil them)(命令式與聲明式的區別)

SplitChunksPlugin也有一些很棒的屬性:

  1. 它永遠不會下載不須要的模塊(只要你不經過名稱強制執行chunk合併)
  2. 在異步chunks下也是高效的
  3. 默認爲異步chunks模式分割
  4. 更加容易使用
  5. 不依賴於chunk
  6. 大可能是自動化配置的

如下是SplitChunksPlugin爲你列舉的幾個例子。這些示例僅顯示默認行爲,附加配置有更多個性化的選擇

注意:你能夠經過optimization.splitChunks進行配置。這些示例說明了一些關於chunk的內容,默認狀況下它只適用於異步chunk,可是使用optimization.splitChunks.chunks:"all"來配置,適用於全部類型的文件(同步、異步chunk

注意:咱們假設此處使用的每一個外部庫都大於30kb,由於代碼優化僅在超出此大小以後才能生效。

Vendors

chunk-a: react, react-dom, some components
chunk-b: react, react-dom, some other components
chunk-c: angular, some components
chunk-d: angular, some other components

webpack將會自動建立兩個vendors chunks,結果以下:

vendors~chunk-a~chunk-b: react, react-dom
vendors~chunk-c~chunk-d: angular
chunk-a to chunk-d: Only the components

Vendors重疊

chunk-a: react, react-dom, some components
chunk-b: react, react-dom, lodash, some other components
chunk-c: react, react-dom, lodash, some components

webpack也會建立兩個vendors chunks,結果以下:

vendors~chunk-a~chunk-b~chunk-c: react, react-dom
vendors~chunk-b~chunk-c:lodash
chunk-a to chunk-c: Only the components

共享模塊

chunk-a: vue, some components, some shared components
chunk-b: vue, some other components, some shared components
chunk-c: vue, some more components, some shared components

假設共享組件的大小大於30kbwebpack將建立一個vendors chunk和一個commons chunk,結果以下:

vendors~chunk-a~chunk-b~chunk-c: vue
commons~chunk-a~chunk-b~chunk-c: some shared components
chunk-a to chunk-c: Only the components

當這些shared components體積小於30kb時,webpack會特地將該模塊複製到chunk-a chunk-b chunk-c三個文件中。他們認爲進行分離所減少的加載體積的總體效果並不如一次額外的加載請求的消耗。

多個共享模塊

chunk-a: react, react-dom, some components, some shared react components
chunk-b: react,react-dom, angular, some other components
chunk-c: react,react-dom, angular, some components, some shared react components, some shared angular components
chunk-d: angular, some other components, some shared angular components

webpack將建立兩個vendors chunk和兩個commons chunk,結果以下:

vendors~chunk-a~chunk-b~chunk-c: react, react-dom
vendors~chunk-b~chunk-c~chunk-d: angular
commons~chunk-a~chunk-c: some shared react components
commons~chunk-c~chunk-d: some shared angular components
chunk-a to chunk-d: Only the components

注意:因爲chunk名稱包括全部原始chunk名稱,所以建議使用長期緩存的生產版本不包括文件名中的[name],或經過optimization.splitChunks.name:false關閉名稱生成.這樣在後續開發中添加了新的引用,也不會變動文件名。

對本文有任何優化建議,可掃描下述二維碼一塊兒討論,同時也但願你們多多關注,會不按期發送一些原創文章

相關文章
相關標籤/搜索