webpack 打包分析,Preloading,Prefetching(13)

獲取全套webpack 4.x教程,請訪問瓦力博客

本小節(jié)主要給大家介紹如何提高代碼的性能?我們從打包工具入手,然后到預提模塊(Preloading),預加載模塊(Prefetching)。

1.打包分析

  • 官方提供的分析工具{:target="_blank"}
  • webpack-chart{:target="_blank"}:webpack stats 可交互餅圖
  • webpack-visualizer{:target="_blank"} :可視化并分析你的 bundle,檢查哪些模塊占用空間,哪些可能是重復使用的
  • webpack-bundle-analyzer{:target="_blank"} :一個 plugin 和 CLI 工具,它將 bundle 內容展示為便捷的、交互式、可縮放的樹狀圖形式
  • webpack bundle optimize helper{:target="_blank"} :此工具會分析你的 bundle,并為你提供可操作的改進措施建議,以減少 bundle 體積大小。

打包分析是指當webpack對我們的代碼打包過后,我們使用分析工具對打包后的文件進行一定的分析,幫助我們看打包后的代碼有沒有繼續(xù)提升的空間。

生成stats.json

您可以通過運行webpack --profile --json> stats.json為此工具生成所需的JSON文件

package.json

{
 "scripts": {
    "dev": "npx webpack-dev-server --config webpack.config.js --mode=development --colors",
    "prod": "npx webpack --config webpack.config.js --mode=production",
    "build": "npx webpack --config webpack.config.js --mode=development --colors"
+    "analyse": "npx webpack --profile --json> stats.json --config webpack.config.js --mode=development --colors"
  },
}

運行webpack

yarn run analyse
ssl

在我們的項目下面生成了一個stats.json文件,將stats.json文件上傳到官方分析工具中就可以了。

2.使用webpackBundleAnalyzer

安裝webpack-bundle-analyzer

yarn add -D webpack-bundle-analyzer

webpack.config.js

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}
ssl

3.prefetch

在聲明import時,使用下面這些內置指令,可以讓webpack輸出resource hint(資源提示)來告知瀏覽器:

  • prefetch(預獲取): 將來某些導航下可能需要的資源
  • preload(預加載):當前導航下可能需要資源

上面我是看中文的文檔,有英文能力的小伙伴可以看英文,這樣理解比較準確。小菜本想在這里說說個人理解,但是寫出來后,感覺語言描述的不是很清楚,那還是用代碼來演示吧。

splitChunks: {
    chunks: 'all'
}

webpack官方默認chunks:async,官方為什么要默認chunks:async呢?當我們在引入loadsh,jquery庫時,如果配置chunks: 'all',那么肯定會幫助我們把loadshjquery單獨拆分開來,但是這樣做并不能提升首頁的代碼性能,原因是在瀏覽器第一次加載時,還是需要我們加載loadsh、jquery庫,只有當我們的代碼第二次加載時,瀏覽器才會從緩存中去找,提高我們第二次頁面加載訪問速度。webpack是想讓我們第一次加載時,訪問速度就是最快。舉個列子

未優(yōu)化的代碼

src/index.js

document.addEventListener('click',()=>{
    const element = document.createElement('div');

    let sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }

    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }

    element.innerHTML =  `0~100的和為${sum}`;
    document.body.appendChild(element)
})

編譯webpack

yarn run build

打開dist/index.html,找到coverage?;蛘呖旖莘绞?code>Ctrl + Shift + P,輸入coverage

ssl

打開后刷新頁面,然后點擊index.js

ssl

可以看到index.js未使用利用率27.9%,我們可以優(yōu)化一下index.js代碼

優(yōu)化后

新建src/util/click.js

function handleClick(){
    const element = document.createElement('div');

    let sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }

    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }
    sum = 0;
    for(let i=1;i<=100;i++){
        sum +=i;
    }

    element.innerHTML =  `0~100的和為${sum}`;
    document.body.appendChild(element)
}

export default handleClick

src/index.js

document.addEventListener('click',()=>{
    import('./util/click').then(({default:func}) =>{
        func();
    })
})

運行webpack

yarn run build
ssl

從上面的截圖可以了解到,index.js未使用率降低到了24.3%,小菜這里有個疑惑就是mian.js的未使用率上升了,按道理應該是要下降的。小菜也只能在這里猜測下,雖然index.js里面的代碼被移到click.js里面,估計demo寫的太簡單,代碼太少,webpack打包后,mian.js的代碼代碼量增加了,從而導致未使用的代碼率上升。如果后面有機會的話,小菜會專門寫一小節(jié)分析下,感興趣的小伙伴也可以自己研究下,然后在評論區(qū)留言分享也行。

ssl

webpack打包后,會有一個1.js文件被分割出來(大家如果想改名字,請查看上一節(jié))那么就會帶來一個問題,比如在首頁上有一個登陸按鈕,首頁加載好后,用戶點擊登陸,然后才會加載登陸程序,這樣會不會影響用戶體驗,如果按照上面那種方式確實會有這個問題。我們希望當主程序加載完成后再去加載子程序,還是上面那個例子,當首頁加載完成后,在瀏覽器空閑的時候去加載登陸程序,這樣一來就解決上面那個問題。

4.使用prefetch優(yōu)化

繼上面demo我們做點小修改

src/index.js

document.addEventListener('click',()=>{
    import(/* webpackPrefetch: true */'./util/click').then(({default:func}) =>{
        func();
    })
})

運行webpack

yarn run build
ssl

打開瀏覽器的控制臺,刷新頁面,可以看到0.js文件被加載了。大家可以把魔法注釋去掉,在刷新瀏覽器看看。

5.使用preload優(yōu)化

src/index.js

document.addEventListener('click',()=>{
    import(/* webpackPreload: true */'./util/click').then(({default:func}) =>{
        func();
    })
})
ssl

打開瀏覽器的控制臺,刷新頁面,可以看到0.js文件也被加載了。

6.prefetch和preload區(qū)別

不正確地使用 webpackPreload 會有損性能,請謹慎使用

preload和 prefetch 指令相比,preload 指令有許多不同之處:

  • preload chunk 會在父 chunk 加載時,以并行方式開始加載。prefetch chunk 會在父 chunk 加載結束后開始加載
  • preload chunk 具有中等優(yōu)先級,并立即下載。prefetch chunk 在瀏覽器閑置時下載
  • preload chunk 會在父 chunk 中立即請求,用于當下時刻。prefetch chunk 會用于未來的某個時刻
  • 瀏覽器支持程度不同

7.總結

webpack官方在配置中chunks: 'async'寫的是異步,是想讓我們編寫異步程序來提高代碼的性能,緩存能夠帶來的代碼提升非常有限,我們后面寫代碼程序應該重點關注代碼利用率,提高代碼利用率才是真正提高代碼性能,如果頁面代碼暫時不用,就采用異步懶加載的形勢,主代碼加載完成后利用空閑時間來加載其他子代碼。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • GitChat技術雜談 前言 本文較長,為了節(jié)省你的閱讀時間,在文前列寫作思路如下: 什么是 webpack,它要...
    蕭玄辭閱讀 12,892評論 7 110
  • webpack 介紹 webpack 是什么 為什么引入新的打包工具 webpack 核心思想 webpack 安...
    yxsGert閱讀 6,670評論 2 71
  • 記得2004年的時候,互聯(lián)網開發(fā)就是做網頁,那時也沒有前端和后端的區(qū)分,有時一個網站就是一些純靜態(tài)的html,通過...
    陽陽陽一堆陽閱讀 3,457評論 0 5
  • 目錄第1章 webpack簡介 11.1 webpack是什么? 11.2 官網地址 21.3 為什么使用 web...
    lemonzoey閱讀 1,829評論 0 1
  • (東北行) 文/菊 松江抱玉島, 碧浪濺珠盤。 波光粼閃, 洲渚湖島隱樓蘭。 花木青蔥郁翠, 雜草叢生綠碧, 夢幻...
    斌之志閱讀 700評論 11 13

友情鏈接更多精彩內容