webpack4.x 系列(二) ☞懶加載 、Preload、Prefetch的講解

我們總是在想,如何讓一些代碼先不加載,而是先讓核心代碼加載,讓用戶能夠快速的看到主頁代碼,而像一些事件按鈕、其他頁面通過某些操作再進行加載,或者在瀏覽器休息時候再進行加載呢!這裏我們講了三種方法去讓代碼優化。本節還介紹一些打包代碼的工具,能夠更好的去分析代碼,然後去分析代碼的使用情況,然後找一個最優的解決辦法,使代碼找到一個平衡點。

一、二節工具介紹,三節、懶加載,四節、preload與Prefetch

一、打包後代碼的分析

我們會對打包的過程做分析,分析步驟:

1.先在package.json裏面的script上面寫上這個,--profile --json > stats.json,如下面所示:

打包會生成一個stats.json的文件

2.然後Install

# NPM
npm install --save-dev webpack-bundle-analyzer
# Yarn
yarn add -D webpack-bundle-analyzer

3.然後Usage (as a plugin)

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

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

打包就會生成下面一樣的圖片:

裏面會包含着各種打包的內容,包括依賴包文件等等,這個可以幫助我們分析哪些東西需要做進一步的優化。

這個模塊會幫助你:

  1. 瞭解你的包裏真正有什麼東西。
  2. 找出什麼模塊構成最大的大小。
  3. 找出錯誤打包的模塊文件。
  4. 通過這個我們可以讓我們的打包文件達到最優。

二、查看代碼的利用率

首先,我們介紹一種瀏覽器的工具使用:

我們打開瀏覽器控制檯,然後ctrl + shift + p,輸入showCover,然後出現下面這個界面:

然後點擊上圖黑色按鈕:如下圖,就會出現代碼利用率的景象。

我們可以用這個來查看代碼的利用率情況,這也是我們經常用來研究頁面性能常用的工具。以後我們可以用代碼覆蓋率去優化我們的性能,而不是講如何去做緩存了。

三、webpack中的懶加載

  • 懶加載,也稱爲按需加載,是一種可以提高網站初始響應速度的方式。
  • 在網站初次加載時,並不會加載全部代碼,而是當用戶完成某些特定操作後,纔會引用新的代碼塊。

安裝依賴:

"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"lodash": "^4.17.15"

文件結構:

+ node_modules
+ src
 - index.js
+ dist
 - index.html

入口文件代碼index.js:

import _ from 'lodash';

function getComponent() {
    var element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    return element;
}

document.addEventListener('click', () => {
    var element = getComponent();
    document.body.appendChild(element);
})

問題1:上面這種方法會很早的將getComponent()加載到頁面中,如果代碼一多就會造成卡頓的情況,如果是在首頁加載,可能會造成白屏的狀況,用戶體驗賊差,我們可以用懶加載(按需加載)的方式,也就是異步加載代碼(需要異步的方法)的形式

懶加載的案例代碼1:

setTimeout(()=>{
    // 也是一個chunk.js,加載後會是一個帶數字的js文件
	import('./xxx.js').then(res => {
		// res就是import返回的數據
		console.log(res.data.message)
	})
}, 1500);

也可以讓用戶需要的時候再加載。

懶加載的案例代碼2:

import _ from 'lodash';

//async返回的是一個promise對象
async function getComponent() {
    const _ = await import('lodash');
    var element = document.createElement('div');
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    // 返回值做爲resolve的參數 
    return element;
}

// 懶加載
document.addEventListener('click', () => {
    // element就是上面return的資源
    getComponent().then((element) => {
        document.body.appendChild(element);
    })
})

 因爲 lodash 模塊僅在 getComponent 函數中使用,而 getComponent 函數僅在 click 事件後執行所以我們可以將加載 lodash 模塊的代碼放在 getComponent 函數當中這樣,只有在發生點擊事件之後,纔會去加載 lodash 模塊,從而達到按需加載的效果

我們也可以從下圖中可以看到,在打開也買你中先不加載代碼,而是在點擊時候加載代碼,從而提高代碼的利用率。

問題2:懶加載是好的,但是當點擊按鈕時候或者每隔一段時間,才能下載相應頁面的js文件,這就導致體驗極其不好,每一次點擊訪問新頁面都要等待js文件下載,然後再去請求接口獲取數據。頻繁出現loading動畫的體驗真的不好。那麼我們可以使用prefetch方式,讓代碼在空閒時候加載出來,而不是點擊某個按鈕或者延遲時間

四、webpack中prefetch

我們在想,有沒有一種方式讓代碼第一次加載時候就能達到最優,而不是利用緩存或是點擊按鈕時候下次加載才能提高訪問的速度。

比如說下面這段代碼:

// click.js
function handleClick() {
  const element = document.createElement('div');
  element.innerHTML = 'hansen';
  document.body.appendChild(element)
}

export default handleClick;
// index1.js

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

當點擊document時候,實現異步加載,這種方式可以讓一些代碼可以慢點加載,在需要使用的時候再進行加載,這也是我們說的但是也會出現一個問題,比如,我們在使用vue做單頁面開發時候,由於單頁面應用頁面過多,可能會導致代碼體積過大,從而使得首頁打開速度過慢。所以切分代碼,優化首屏打開速度尤爲重要。

所以如果我們在進入首頁後,在瀏覽器的空閒時間提前下好用戶可能會點擊頁面的js文件,這樣首屏的js文件大小得到了控制,而且再點擊新頁面的時候,相關的js文件已經下載好了,就不再會出現loading動畫。 

所以我們引入了prefetch,讓文件可以在空閒時候加載,具體方法如下:在模塊裏面添加魔法註釋/* webpackPrefetch: true */

// index1.js

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

這樣子,0.js會在空閒時候被加載,注意:0.js只是被加載,沒有被利用

當點擊document時候,0.js被加載出來,他只需要1ms鍾了,是不是更快了呢。

說到了這裏應該就結束了吧,小夥伴會問,Proload還沒說呢!哈哈,你們可細心,那這裏就介紹下proload,Preload是和父級元素並行加載的,可以被立即使用,通常用於本頁面要用到的關鍵資源。如果使用webpack打包,他也是通過在import模塊中添加魔法註釋就可以了,像這樣子/* webpackPreload: true */。其實有時候,我們可以直接將preload和prefetch用於link標籤使用。


附加

我們可以把Preload和Prefetch直接寫在link標籤上:

1.Preload

<link rel=“preload”> 

preload 提供了一種聲明式的命令,讓瀏覽器提前加載指定資源(加載後並不執行),需要執行時再執行

這樣做的好處在於:

  1. 將加載和執行分離開,不阻塞渲染和document的onload事件
  2. 提前加載指定資源,不再出現依賴的font字體隔了一段時間才刷出的情況

preload通常用於本頁面要用到的關鍵資源,包括關鍵js、字體、css文件。preload將會把資源得下載順序權重提高,使得關鍵數據提前下載好,優化頁面打開速度。

2.prefetch

<link rel=“prefetch”>

這段代碼告訴瀏覽器,這段資源將會在未來某個導航或者功能要用到,但是本資源的下載順序權重比較低。也就是說prefetch通常用於加速下一次導航,而不是本次的,比如下一個頁面會用到的資源,點擊事件後彈出model框等等。

被標記爲prefetch的資源,將會被瀏覽器在空閒時間加載。

Preload和Prefetch的區別

下面是Preload和Prefetch的區別吧:

  • 一個預加載塊(preload)開始與父塊並行加載。預取的塊(prefetch)在父塊完成加載後啓動。
  • 預加載塊(preload)具有中等優先級,可以立即下載。而預取塊(prefetch)在瀏覽器空閒時下載預取的塊。
  • 一個預加載的塊(preload)應該被父塊立即請求。預取的塊(prefetch)可以在將來的任何時候使用。
  • 瀏覽器的支持能力是不同的。

雖然說prefetch或者是preload好,但是我們千萬要記得,不要所有的異步加載模塊都使用這個東西,我們應該根據自己的業務去加載,否則頁面性能不是達到最優而是長時間的等待加載。

總結:

不管懶加載還是預加載,只有適合自己,適合業務的纔是最好的!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章