webpack4 對 chunk graph
(代碼塊關係網格) 進行了一些重大改進並用新的優化策略實現了 chunk spliting
(對CommonsChunkPlugin的一種改進)。vue
咱們看下老 chunk graph
的一些缺點。node
在老的 chunk graph
中,chunks
經過父子關係來鏈接且 chunks
包含了 moudles
的。react
當一個擁有父塊的 chunk
被加載時,就能夠肯定它至少有一個父級已經加載完了。優化策略就是使用了這個原理。即當 chunk
的父塊同時擁有同一個 module
時,這個 module
就能夠今後 chunk
移除,由於它在任何狀況下都已經可用了。webpack
入口點(entry)或異步拆分點(async import)引用了的 chunk
是並行加載的。web
這種關係使得實現「分割」 chunks
變得困難。例如使用 CommonsChunkPlugin
時就會發生這種狀況。一個或多個 chunks
模塊被移除並放進一個新的 chunk
,這個 chunk
須要被鏈接到 chunk graph
中。但要怎麼作呢?當作老 chunk
的父塊?仍是子塊?CommonsChunkPlugin
把它做爲父塊,但這在技術上是錯誤的,會對其餘優化產生負面影響(父塊信息不許確)。緩存
新的 chunk graph
引入了一個新對象:ChunkGroup
。ChunkGroup
包含了 Chunks
。dom
在一個入口點或異步拆分點引用了一個 ChunkGroup
,這意味着此組包含的全部 Chunks
都是並行的。一個 Chunk
能夠被多個 CHunkGroups
引用。異步
Chunk
之間再也不存在父子關係,而存在於 ChunkGroups
之間的關係中。async
如今 Chunks
的「分割」能夠實現了。分割出的新 Chunks
被添加到全部包含原 Chunk
的 ChunkGroups
,這不會對父子關係產生負面影響。優化
如今解決了這個問題,咱們能夠開始更多地使用 chunk
分割了。咱們能夠不冒破壞 chunk graph
的風險地拆分任何 chunk
。
CommonsChunkPlugin
還有許多問題:
chunks
上效率低。全部新的插件誕生了:SplitChunksPlugin
。
它使用 module
重複次數和類別(即node_modules)做爲依據,實現自動識別應該怎樣拆分 chunks
。
這是一種範式轉移。CommonsChunkPlugin
就像是:「快給我加一個新的 chunck
而後把全部匹配 minChunks
規則的模塊移進去」。SplitChunksPlugin
則像是:「這裏有一份圖紙,想辦法實現它們」。(命令式 vs 聲明式)
SplitChunksPlugin
還有一些別的好特性:
chunks
仍然高效chunks
就是打開的chunks
chunk graph
不依賴 hacks
手段這裏有一些 SpitChunksPlugin
能夠爲你作些什麼的例子。這些例子只展現默認行爲。自定義配置會有更多的結果。
注意: 你能夠經過 optimiztion.splitChunks
對其進行配置。例子中關於 chunks
的,默認狀況下只在異步塊(async chunks)中起做用,不過配置 optimiztion.splitChunks.chunks: "all"
可使直塊(initial chunks)也其做用。
注意:咱們假設這使用的全部第三方庫都超過30kb,由於優化只會大於此大小後發生。
chunk-a
: react, react-dom, 一些組件 chunk-b
: react, react-dom, 一些其餘組件 chunk-c
: angular, 一些組件 chunk-d
: angular, 一些其餘組件
webpack會自動添加兩個 vendors chunks
,像下面這樣:
vendors~chunk-a~chunk-b
: react,react-dom vendors~chunk-c~chunk-d
: angular chunk-a
至 chunk-d
: 只有組件
chunk-a
: react, react-dom, 一些組件
chunk-b
: react, react-dom,lodash, 一些其餘組件
chunk-c
: react,react-dom.lodash 一些組件
一樣的,webpack會自動添加兩個 vendors chunks
,像下面這樣:
vendors~chunk-a~chunk-b
: react,react-dom
vendors~chunk-c~chunk-d
: lodash
chunk-a
至 chunk-c
: 只有組件
chunk-a
: vue, 一些組件, 一些共享組件
chunk-b
: vue, 一些其餘組件, 一些共享組件
chunk-c
: vue, 一些組件, 一些共享組件
假設共享組件的大小大於30kb,webpack 會添加一個新 vendors chunk
和 一個 commons chunk
, 就像這樣:
vendors~chunk-a~chunk-b~chunk-c
: vue
commons~chunk-a~chunk-b~chunk-c
: 一些共享組件
chunk-a
至 chunk-c
: 只有組件
當共享組件大小小於30kb,webpack 會特地將chunk-a
中的模塊複製到 chunk-b
中,咱們認爲減小的下載大小不值得爲此單獨加載模塊而發起額外請求。
chunk-a
: react, react-dom, 一些組件,一些共享的react組件
chunk-b
: react, react-dom, angular, 一些其餘組件
chunk-c
: react,react-dom,angular, 一些組件, 一些共享的react組件,一些共享的angular組件
chunk-d
: angular, 一些其餘組件, 一些共享的angular組件
webpack 添加兩個 vendors chunks
和兩個 commons chunks
vendors~chunk-a~chunk-b~chunk-c
: react,react-dom
vendors~chunk-b~chunk-c~chunk-d
: angular
commons~chunk-a~chunk-c
: 一些react共享組件
commons~chunk-c~chunk-d
: 一些angular共享組件
chunk-a
至 chunk-d
: 只有組件
注意:因爲 chunk
名稱由全部 chunk
來源名稱組合而成,所以建議在長期緩存的生成環境中,文件名不應該含有[name],或者經過 optimization.splitChunks.anme:false
關閉建立名稱。不然在添加更多具備相同 vendors
的 chunks
時,先前的文件會失效。
翻譯原文地址:webpack 4: Code Splitting, chunk graph and the splitChunks optimization | 做者:Tobias Koppers