Webpack 4教程 - 第八部分 使用prefetch和preload進行動態加載

轉載請註明出處:葡萄城官網,葡萄城爲開發者提供專業的開發工具、解決方案和服務,賦能開發者。
原文出處:https://wanago.io/2018/08/13/webpack-4-course-part-seven-decreasing-the-bundle-size-with-tree-shaking/html

 

本系列的第一篇文章中,咱們討論了導入(import)和導出(export)。此次咱們深刻介紹動態導入(dynamic import),它值得專門用一篇文章來介紹。咱們會介紹動態導入是什麼以及如何使用它們。開始吧!webpack

在過去,ECMAScript模塊是徹底靜態的。你必須在運行代碼以前指明想要導入和導出的東西。隨着動態導入提案的出現,咱們有了額外的選擇,即動態地導入模塊。如今它進行到了TC39流程的第三個階段。有了它,你就能夠添加動態導入模塊了。使用它時,你可能會根據用戶及其操做行爲的作相應處理。好比,你有一個單頁應用,只有當用戶決定打開它的子頁面時才加載特定代碼。這樣能夠大幅節省應用的初始加載時間。git

使用動態導入github

動態導入操做符是做爲函數使用的。它接受一個字符串參數,返回一個Promise。當模塊加載好後,這個Promise被resolve。web

若是你想了解更多關於Promise的內容,可查看以實現一個排序算法爲例解釋Promise和回調函數正則表達式

1算法

2promise

3瀏覽器

4網絡

5

6

7

8

9

document.addEventListener("DOMContentLoaded", () => {

  const button = document.querySelector('#divideButton');

  button.addEventListener('click', () => {

    import('./utilities/divide')

      .then(divideModule => {

          console.log(divideModule.divide(6, 3)); // 2

      })

  });

});

在瀏覽器的開發者工具,若是打開Network標籤,你能夠看到,模塊開始下載的發生在點擊按鈕以後,而不是在此以前。值得注意的是,若是再次點擊按鈕,包含了拆分後的模塊文件不會再次被下載。

在Webpack中使用動態導入,會新增一個chunk,咱們視做異步chunk

異步chunk在教程的第四部分-使用SplitChunksPlugin分離代碼中有介紹。

像這樣的chunk會被打包進單獨的文件。當使用表達式建立指向其文件的路徑時,你須要當心。考慮以下例子:

1

2

3

4

5

6

7

8

9

10

11

12

let fileName = '';

 

document.addEventListener("DOMContentLoaded", () => {

  const button = document.querySelector('#divideButton');

  fileName = 'divide';

  button.addEventListener('click', () => {

    import(`./utilities/${fileName}`)

      .then(divideModule => {

        console.log(divideModule.divide(6, 3)); // 2

      })

  });

});

以上代碼在你的項目中被打包事後,你會發現Webpack在utilities文件夾下爲每一個模塊單首創建了異步chunk。這是由於Webpack不能在編譯時知道哪些模塊須要被導入。

你還須要知道像import(pathToFile)這樣的徹底的動態聲明是不起做用的,由於Webpack至少須要一部分文件路徑信息。這是由於pathToFile能夠是你工程中任何文件的路徑,而Webpack會爲每一個模塊在給定的文件夾中建立異步chunk。你能夠自定義此行爲,咱們下面就會這麼作。

使用在Webpack中使用魔法註釋

導入模塊的規範不容許你在導入時使用除了文件名之外的參數。幸運的是,有了Webpack,你能夠利用所謂的**魔法註釋(magic comments)**來使用附加參數。

webpackInclude 和 webpackExclude

在以前的小節,咱們提到Webpack會爲每一個模塊在咱們給定的文件夾中建立異步chunk。雖然這是默認行爲,但它能夠修改。

其中一種方法是使用webpackExclude,它是一個正則表達式,用以匹配潛在的可被導入的文件。任何匹配到的文件都不會被打包進來。  

1

2

3

4

import(

  `./utilities/${fileName}`

  /* webpackExclude: /subtract.js$/ */

)

以上代碼表示,文件 subtract.js 文件不會被打包進來,即便它在 utilities 目錄下。

與之相反的一個參數叫作webpackInclude。使用它時,只有匹配了正則表達式的模塊會被打包。

webpackMode

webpackMode屬性定義了resolve動態模塊時的模式。支持如下模式:

lazy

這是默認模式。它爲每一個動態導入的模塊建立異步chunk

lazy-once

使用它,會爲知足導入條件的全部模塊建立單一的異步chunk

1

2

3

4

5

6

7

import(

  `./utilities/${fileName}`

  /* webpackMode: "lazy-once" */

)

  .then(divideModule => {

    console.log(divideModule.divide(6, 3)); // 2

  })

以上代碼表示,Webpack會爲全部 utilities 目錄下的全部模塊共同建立一個異步chunk。它會致使用戶以一個文件下載全部的模塊。

eager

此模式會阻止Webpack生成額外的chunk。全部導入的模塊被包含在當前chunk,因此不須要再發額外的網絡請求。它仍然返回一個Promise,但它被自動resolve。使用eager模式的動態導入與靜態導入的區別在於,整個模塊只有當**import()**掉用以後才執行。

weak

完全阻止額外的網絡請求。只有當該模塊已在其餘地方被加載過了以後,Promise才被resolve,不然直接被reject。

webpackChunkName

它是新chunk的名字,能夠和[index]、[request]變量一塊兒使用。

[index]在當前動態導入聲明中表示文件的索引。另外一方面,[request]表示導入文件的動態部分。

1

2

3

4

import(

  `./utilities/${fileName}`

  /* webpackChunkName: "utilities-[index]-[request]" */

)

以上代碼可能生成例如 utilities-0-divide.js 這樣的文件名。

請注意,若是在某些狀況下,肯定只有一個異步chunk(好比原本就沒有動態生成路徑,或者使用了lazy-once模式),[index]和[request]就不會被使用了。

使用預先拉取和預先加載提高性能

Webpack 4.6.0爲咱們提供了預先拉取(prefetching)和預先加載(preloading)的功能。使用這些聲明能夠修改瀏覽器處理異步chunk的方式。

預先拉取

使用預先拉取,你表示該模塊可能之後會用到。瀏覽器會在空閒時間下載該模塊,且下載是發生在父級chunk加載完成以後。  

1

2

3

4

5

import(

  `./utilities/divide`

  /* webpackPrefetch: true */

  /* webpackChunkName: "utilities" */

)

以上的導入會讓<link rel="prefetch" as="script" href="utilities.js">被添加至頁面的頭部。所以瀏覽器會在空閒時間預先拉取該文件。

預先加載

在資源上添加預先加載的註釋,你指明該模塊須要當即被使用。異步chunk會和父級chunk並行加載。若是父級chunk先下載好,頁面就已可顯示了,同時等待異步chunk的下載。這能大幅提高性能。  

1

2

3

4

5

import(

  `./utilities/divide`

  /* webpackPreload: true */

  /* webpackChunkName: "utilities" */

)

以上代碼的效果是讓<link rel="preload" as="script" href="utilities.js">起做用。不當地使用wepbackPreload會損害性能,因此使用的時候要當心。

總結

此次咱們學習瞭如何使用動態導入提高應用的性能。它們能顯著減小頁面的初次加載時間。使用可傳入Webpack的額外參數,你能夠更進一步地定製它,而且添加上對預先拉取和預先加載的支持。全部這些,都會優化你的用戶體驗,讓你的網站更加靈動。

相關文章
相關標籤/搜索