本文全部的內容均基於
webpack@4.42.0
所撰寫。閱讀本文以前需瞭解Webpack
的一些基本概念,如:entry
、chunk
、module
等。css
代碼分割是 Webpack
最引人注目的特性之一。這個特性容許開發者將代碼分割成不一樣的包,而後能夠按需加載或並行加載這些包。它能夠用來實現更小的包,並控制資源加載優先級,若是使用正確,將對加載時間產生重大影響。node
首先介紹一下 Webpack
默認的代碼分割策略。webpack
webpack will automatically split chunks based on these conditions:web
- New chunk can be shared OR modules are from the node_modules folder
- New chunk would be bigger than 30kb (before min+gz)
- Maximum number of parallel requests when loading chunks on demand would be lower or equal to 5
- Maximum number of parallel requests at initial page load would be lower or equal to 3
上面這段話來自 Webpack
的官方文檔,說的是 Webpack
會在知足下面的條件時自動進行 chunk 的分割 (ps:若是沒有特殊配置的話,只有異步加載的 chunk 會自動進行分割)。bash
chunk
能夠被共享或者 chunk
裏的 module
來自於 node_modules
文件夾chunk
文件大小大於 30kb(壓縮前)chunk
內部的最大並行請求數不超過 5 個知足上面的四個條件 Webpack
就認爲能夠進行代碼分割,前兩個條件應該比較好理解,這裏解釋下後兩個條件的意思吧:併發
chunk
內部的最大並行請求數不超過 5 個簡單來講就是加載 chunk
所發送的請求不能超過 5 個。舉個例子:異步
a.js
依賴了 1.js
、2.js
、3.js
、4.js
這四個文件,且這四個文件知足了代碼分割的前兩個條件 (被共享且大於 30kb)。這個時候就會分割出五個 chunk
,分別是:a.chunk.js
、1.chunk.js
、2.chunk.js
、3.chunk.js
、4.chunk.js
。此時加載 chunk~a
的併發請求數就剛好是 5 個,編譯後的加載代碼大體以下:async
// t.e 是加載的 chunk 的方法,t.e 的參數應該是 chunk 的 id,爲了容易閱讀,我這裏用了 chunk 的名稱替代。
Promise.all([t.e('1.chunk'),t.e('2.chunk'),t.e('3.chunk'),t.e('4.chunk'),t.e('a.chunk')]).then(() => // do some thing)
複製代碼
若是 a.js
又依賴了 5.js
,,這個時候並不會分割出 5.chunk
,由於若是分割出 5.chunk
,那麼加載 a.chunk
的請求就是 6
個了, 5.js
的內容會被合併到 a.chunk
中。ui
這裏的初始化頁面能夠理解爲加載 entry
,換句話說就是加載 entry
的並行請求的最大數量不超過 3 個,如今就比較好理解了,和上一個條件基本一致,只不過一個是針對 entry
的,一個是針對普通的 chunk
的。這個配置是爲了對代碼分割的 chunk
數量進行必定的限制,避免分割出太多chunk
致使請求數量過多的狀況。spa
要注意的是:
js
之外的請求好比css
。上面介紹的都是 Webpack
代碼分割的默認策略,這些策略是 Webpack
團隊認爲的最佳實踐。 若是你在項目有特殊的需求,好比認爲默認的 30kb 太大了,你想超過 10kb 就進行分割。Webpack
也提供了咱們一些配置去修改分割策略,這就是 Webpack
中的 optimization.splitChunks
配置,下面就介紹幾個比較相對重要的配置,完整的配置能夠查看文檔。
splitChunks.chunks
function (chunk) | string
chunks
配置的是要針對哪些 chunk
進行代碼分割,以前有提到過,默認只會分割異步的加載的 chunk
。chunks
的值爲 string
時,有效的值爲all
, async
和initial
。
module.exports = {
//...
optimization: {
splitChunks: {
// 分割全部類型的 chunk
chunks: 'all'
}
}
};
複製代碼
module.exports = {
//...
optimization: {
splitChunks: {
chunks (chunk) {
// 除了 `my-excluded-chunk` 都進行分割
return chunk.name !== 'my-excluded-chunk';
}
}
}
};
複製代碼
splitChunks.minChunks
number
minChunks
指的是在代碼分割以前 module
至少被幾個 chunk
共享。默認值爲1
。
splitChunks.minSize
number
minSize
對應的就是分割策略中的第二個條件中的 30kb
的限制,開發者能夠根據項目的實際狀況靈活調節它的大小。
splitChunks.maxSize
number
這個配置是設置分割出來的 chunk
的最大文件大小的,默認值爲 0
,也就是沒有上限。設置了該屬性,Webpack
就會盡量地把 chunk
的大小限制在maxSize
的值以內,不過一個完整的module
的代碼無法分割成幾段,因此該超過仍是會超過的。
你能夠經過設置這個屬性來分割出更多、更小的 chunk
,不過隨之而來的就是更多的加載 chunk
的請求。
splitChunks.maxAsyncRequests
number
maxAsyncRequests
對應的是分割策略中的第三條的配置,默認值爲 5
splitChunks.maxInitialRequests
number
maxInitialRequests
對應的是分割策略中的第四條的配置,默認值爲 3
splitChunks.cacheGroups
cacheGroups
是 splitChunks
中最核心的配置之一,它的配置項包括 splitChunks.*
下的全部配置,且還多了test
、priority
、reuseExistingChunk
三個配置項。
cacheGroups
中的配置會覆蓋 splitChunks
中的配置,並且有優先級之分(經過 priority
設置優先級),cacheGroups
主要的用途是針對不一樣的 chunk
設置不一樣的分割策略,這能夠大大提高代碼分割的靈活性,筆者在這裏就不詳細展開說明使用方法了,感興趣的能夠參考官方文檔。