在最開始的時候,webpack都是將全部的代碼打包到一個文件中,可是當項目過大的時候,頁面所須要加載的時間就會變長,這個時候咱們就須要Code Splitting
對文件進行分塊,實現代碼的按需加載。node
接下來咱們來看看下面兩種方式:webpack
當用第一種方式的時候, 咱們須要等打包文件加載完成以後,纔會去實現文件裏面的邏輯,再將頁面展現出來。那麼這樣帶來的問題是什麼呢,有一個問題想必你們都很清楚,那就是打包文件很大,加載時間很長。web
那還有一個問題是什麼呢,咱們都知道,lodash是一個第三方庫,咱們不會隨便去修改它,可是業務邏輯是常常會被改變的。假設咱們修改了業務代碼,那咱們就須要從新去加載打包中的js文件,才能獲取到最新的代碼,顯示最新的內容。由於業務代碼和第三方庫都在同一個文件中,因此lodash相應的也要被從新加載。緩存
index.jsapp
// 同步邏輯
// 第一種方式
// 首次訪問頁面的時候, 加載main.js 2mb
// 當業務邏輯發生變化時 又要加載main.js 2mb的內容
import _ from 'lodash' //假設1mb
// 業務邏輯 1mb
console.log(_.join(['a','d','c'], "***"));
// 中間省略幾千行代碼....
console.log(_.join(['a','b','c'], "***"));
複製代碼
第二種方式咱們將上面代碼拆分紅了兩個文件main.js
和lodash.js
,咱們將不須要修改的第三方庫拎出來放在一個單獨的文件中,當頁面業務邏輯發生變化的時候,只須要加載main.js頁面就能夠了。異步
這種動態加載的方式就能提高咱們頁面展現的速度,相應的也提升了性能。async
index.js性能
// 第二種方式
// main.js被拆成lodash.js(1Mb), main.js(1mb)
// 當業務邏輯發生變化時,只要加載main.js便可(1MB)
// 業務邏輯 1mb
console.log(_.join(['a','d','c'], "***"));
console.log(_.join(['a','b','c'], "***"));
複製代碼
lodash.js學習
// 加載了lodash,而後將lodash掛載到了全局上面
import _ from 'lodash'; //1mb
window._ = _
複製代碼
Code Splitting
其實本質上是和webpack沒有任何關係的,但爲何只要一說到webpack,咱們在不少時候都能聽到webpack裏面有Code Splitting
呢?這是由於webpack裏面有一些插件能夠很是容易的幫助咱們實現Code Splitting
。ui
在webpack4裏面有一個插件splitChunksPlugin,這個插件直接與webpack作了捆綁,不須要安裝,直接就能夠拿來用了。這樣的話咱們進行代碼分割就很是容易了。
同步代碼分割
咱們先將以前的lodash.js
和index.js
合併,而後咱們在webpack.config.js
裏面配置一個optimization
:
optimization: {
splitChunks: {
chunks: 'all'
}
}
複製代碼
咱們從新對代碼進行打包,查看dist目錄:
咱們能看見,只要作一個很是簡單的配置,就能實現代碼分割,徹底不須要咱們再手動進行文件的拆分。
異步代碼的分割
上面咱們說的是同步加載。那麼接下來咱們看看異步加載吧!
// 異步加載lodash
function getComponent() {
return import('lodash').then(({default: _}) => {
const element = document.createElement('div')
element.innerHTML = _.join(["linna", "mao"], '-')
})
}
getComponent().then(element => {
document.body.appendChild(element)
})
複製代碼
若是你們實踐過的話,就知道即使咱們不在webpack.config.js
中配置optimization
,異步載入的組件也會自動打包再一個單獨的文件中。
從上圖中咱們能夠看到,異步代碼分割中,dist
目錄中打包生成的文件是一個0.js
,這個0是Code Splitting
產生的一個id的值。
若是咱們想要將它改爲咱們能夠識別的名字,咱們就能夠在上面異步代碼的第一個參數前面添加/*webpackChunkName:"lodash"*/
,這個是在異步加載組件中存在的一個magic comment(語法註釋)。
magic comment只能在官方動態加載組件的插件使用
//詳細代碼看異步代碼中的index.js
return import(/*webpackChunkName:"lodash"*/'lodash').then(({default: _})
複製代碼
打包後咱們能夠看到vendors~lodash.js
,那麼爲何會在lodash
前面添加vendors
呢?這裏咱們就須要去看咱們的配置了,官方文件中在optimization
中會有一個默認配置
splitChunks: {
chunks: "async",
minSize: 30000,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
priority: -20,
reuseExistingChunk: true
}
}
}
複製代碼
其中:
更多詳解參考官網split-chunks-plugin
aysnc
的意思是對異步代碼進行分割,這就是爲何在以前代碼中異步代碼分割不須要進行配置的緣由。vendors~lodash.js
。cacheGroup
裏的名字有效。node_modules
中的時候,符合vendors
,就會在分割文件中添加前綴vendors
,當有多個node_modules
模塊時候,就會將全部引用模塊先進行緩存,最後的時候一塊兒打包成vendors
文件。index.js
引入一個本身寫的js文件,它就找到cacheGroup
,不符合vendors
的時候,就會進入default
中,這個時候打包文件的前綴就會有default
。default
中全部的模塊都是符合的,當一個模塊既符合vendors
又符合default
的時候,那麼priority
的值越大,優先級越高。注:此文爲本人學習過程當中的筆記記錄,若是有錯誤或者不許確的地方請大佬多多指教~