
打包分析
什么是打包分析
webapck打包分析是指在webpack打包后,通過一些插件來對我們的打包是否合理做出的分析。
對于這樣的工具,有官網(wǎng)提供的,也有一些第三方的插件。我們可以參考官網(wǎng)去做相應(yīng)的配置和選擇webpack打包分析
我個(gè)人比較常用的是webpack-bundle-analyzer,他的打包分析就像下面這樣
可以很清晰的通過可視化的方式,讓我們了解當(dāng)前的打包情況,大家可以根據(jù)自己的選擇,選擇相應(yīng)的插件進(jìn)行配置和打包分析,通過打包分析,我們可以很清楚的發(fā)現(xiàn)打包中的潛在問題,并作出相應(yīng)的調(diào)試。
Preloading/Prefetch
之前我們了解了代碼分割,并用lodash的例子做了演示,我們通過代碼分割的方式,將第三方庫做了單獨(dú)的打包,這樣可以提高第二次訪問的速度,顯然,這樣是有一些不太滿足我們的預(yù)期的,我們更期望,第一次訪問頁面的速度就很快。這就涉及到了我們下面要講解的內(nèi)容Preloading/Prefetch
性能分析
我們將index.js改成下面這樣,然后打包并運(yùn)行index.html
document.addEventListener('click', () => {
const element = document.createElement('div')
element.innerHTML = 'hello Preloading'
document.body.appendChild(element)
})
首先代碼運(yùn)行是沒有一點(diǎn)問題的,我們通過點(diǎn)擊事件去給body中插入一個(gè)元素,但這真的就是最佳的寫法嗎?沒有再精簡的余地了嗎?我們通過瀏覽器運(yùn)行index.html,并在控制臺中輸入ctrl+shift+P,在彈出的選擇輸入框中輸入coverage這樣的字,并打開show Coverage,像下面這樣
點(diǎn)擊標(biāo)黃區(qū)域的按鈕,刷新頁面,這時(shí)候,發(fā)現(xiàn)下面出現(xiàn)了分析條,這就是對代碼中利用率的分析,我們通過分析條進(jìn)入到index.js中,到最下面找到我們自己的邏輯,發(fā)現(xiàn)代碼的利用率是這樣的
當(dāng)我們點(diǎn)擊頁面,這個(gè)時(shí)候代碼的利用率才變成100%,也就是說,在頁面剛加載的時(shí)候
const element = document.createElement('div')
element.innerHTML = 'hello Preloading'
document.body.appendChild(element)
這段代碼是沒有被利用的,再點(diǎn)擊的時(shí)候,才利用起來。也就是我們一開始沒有執(zhí)行的代碼,也會隨著頁面加載加載進(jìn)來,這就造成了性能的浪費(fèi),webpack希望,我們這樣的交互應(yīng)該這樣去處理
document.addEventListener('click', () => {
import('./click').then(({default: func}) => {
func()
})
})
click.js
function handleClick () {
const element = document.createElement('div')
element.innerHTML = 'hello Preloading'
document.body.appendChild(element)
}
export default handleClick
這個(gè)時(shí)候,再執(zhí)行上面的分析操作,你會發(fā)現(xiàn),代碼的利用率提高了,當(dāng)然哈,不同版本的瀏覽器可能和我操作的不一樣,展示的也不一樣,這里通過我的實(shí)驗(yàn)做說明,理論上都是這樣的,通過上面的實(shí)驗(yàn)我們會發(fā)現(xiàn),webpack更希望我們把代碼的邏輯寫成上面的樣子。這樣就會讓代碼的利用率變高,同時(shí)加載的也會更快。所以只有多寫異步組件,才能真正的提升意面性能這也就是為什么在splitChunksPlugin中的chunks選項(xiàng),默認(rèn)是async的原因。因?yàn)橥降拇a,對于優(yōu)化來說只能增加一個(gè)緩存,而對于頁面性能的優(yōu)化,也是非常有限的。
那么,在實(shí)際項(xiàng)目中,我們怎么去使用這樣的異步的引入呢?比如在一些業(yè)務(wù)場景中,經(jīng)常會有彈層的操作,那么其實(shí)我們就可以將彈層代碼加載變成異步,但這樣又會導(dǎo)致,點(diǎn)擊呼出彈層的交互變得比較慢,為解決這一問題,我們將使用Preloading/Prefetch
Preloading/Prefetch
設(shè)想這樣一種場景,我們在加載整個(gè)首頁資源的時(shí)候不去加載彈層的資源,也不在去點(diǎn)擊的時(shí)候才去加載對應(yīng)的資源,而是在首頁資源加載完畢到點(diǎn)擊呼出彈層這個(gè)空閑時(shí)間去操作,是不是就既能滿足首頁加載快,又能滿足呼出彈層快的操作呢?我們還是通過模擬代碼來做這個(gè)實(shí)驗(yàn),我們對之前的index.js做下面的修改
document.addEventListener('click', () => {
import(/*webpackPrefetch: true*/'./click').then(({default: func}) => {
func()
})
})
上面魔法注釋的意思是,我們等主要代碼加載完畢后,不用等點(diǎn)擊事件去執(zhí)行就去加載對應(yīng)的資源,我們打包后,通過netWork來監(jiān)控一下資源的加載,我們發(fā)現(xiàn),當(dāng)頁面剛一加載的時(shí)候就已經(jīng)是這樣的
這一點(diǎn)也是符合我們上面所說的,但是當(dāng)你去執(zhí)行點(diǎn)擊事件的時(shí)候,你會發(fā)現(xiàn),0.js又被加載了一次,但這一次,加載時(shí)間縮短了不少,這樣就達(dá)到了我們上面的預(yù)期,這就是Prefetch
那關(guān)于preload呢,其實(shí)和prefetch使用方法差不多,之類就不帶著大家演示了,其區(qū)別在于,PreLoad是和頁面主代碼一起加載的,這樣其實(shí)有點(diǎn)不是我們所期望的,但大家也應(yīng)該知道這個(gè)概念
寫在最后
本文通過打包分析,發(fā)現(xiàn)了打包過程中的性能問題,并通過Prefetch和Preload的方式解決,同時(shí)我們也應(yīng)該注意到,關(guān)于頁面性能優(yōu)化,我們不能把希望寄托于瀏覽器的緩存,應(yīng)該更去關(guān)注代碼的利用率。