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

来源:https://www.cnblogs.com/powertoolsteam/archive/2019/05/16/10873677.html
-Advertisement-
Play Games

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


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

 

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

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

使用動態導入

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

如果你想瞭解更多關於Promise的內容,可查看以實現一個排序演算法為例解釋Promise和回調函數

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會被打包進單獨的文件。當使用表達式創建指向其文件的路徑時,你需要小心。考慮如下例子:

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,它是一個正則表達式,用以匹配潛在的可被導入的文件。任何匹配到的文件都不會被打包進來。  

import(
  `./utilities/${fileName}`
  /* webpackExclude: /subtract.js$/ */
)

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

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

webpackMode

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

lazy

這是預設模式。它為每個動態導入的模塊創建非同步chunk

lazy-once

使用它,會為滿足導入條件的所有模塊創建單一的非同步chunk

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]表示導入文件的動態部分。

import(
  `./utilities/${fileName}`
  /* webpackChunkName: "utilities-[index]-[request]" */
)

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

請註意,如果在某些情況下,確定只有一個非同步chunk(比如本來就沒有動態生成路徑,或者使用了lazy-once模式),[index]和[request]就不會被使用了。

使用預先拉取和預先載入提升性能

Webpack 4.6.0為我們提供了預先拉取(prefetching)和預先載入(preloading)的功能。使用這些聲明可以修改瀏覽器處理非同步chunk的方式。

預先拉取

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

import(
  `./utilities/divide`
  /* webpackPrefetch: true */
  /* webpackChunkName: "utilities" */
)

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

預先載入

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

import(
  `./utilities/divide`
  /* webpackPreload: true */
  /* webpackChunkName: "utilities" */
)

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

總結

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先我們在項目中導入這個框架: 在AndroidManifest文件當中添加網路許可權: 下麵是我們的首頁佈局:在這個佈局當中我們將Volley框架的所有功能都做成了一個按鈕,按下按鈕之後就會在“顯示結果”下麵顯示結果,顯示結果下麵使用了一個ScrollView,併在ScrollView下麵嵌套了一個 ...
  • 1、普通對話框: 給出提示信息,有yes、no兩個按鈕。 所有對話框都有 setTitle()、setMessage()、setIcon()、show()、hide()的方法。 其中 setTitle()、setMessage()、setIcon()既可以在create()之前使用,也可以在crea ...
  • ImageView 顯示圖片 常用屬性: src 要顯示的圖片 foreground 前景圖 backgrund 背景圖 alpha 透明度 clickable 是否可以點擊 onClick 單擊事件 另外,還有一堆用於裁剪、縮放、著色等設置圖片顯示的屬性。 ...
  • RadioButton 單選按鈕 常用屬性: text 文本 checked=“true” 預設選中 一組互斥的單選按鈕要放在RadioGroup中。RadioGroup常用屬性: orientation 該組單選按鈕的排列方向。 示例: ...
  • Button 按鈕 常用屬性: onClick 單擊時要執行的函數 Button設置事件監聽的4種方式: 1、在佈局中設置屬性onClick="函數名",在對應的.java文件中編寫函數。函數名要相同。 形參View是必須的。 2、在佈局對應的.java中給單個控制項設置事件監聽: 可以使用匿名內部類 ...
  • 1、TextView 顯示文本信息 常用屬性: layout_width/height 控制項的寬/高 width/heigth 文本區域的寬/高 text 顯示的文本 textSize 字型大小,sp textColor 字體顏色 textStyle 字體樣式(斜體、粗體) maxLength 文本的最 ...
  • 首先上圖: 我們可以看到上面這個我所編寫的界面上,戰狼這一個模塊則使用了cardview控制項,下麵我們來看看它是怎麼使用的:這裡是cardview線上性佈局下的的佈局代碼: 十分容易就可以搞定了,但是不要忘記了需要在build.gradle文件下使用我們引入的庫哈: 上面這行代碼是必不可少的啦! ...
  • 首先我們先上圖: 下麵是主頁面的代碼,activity_main.xml: 2.mainactivity.java 3.創建menu文件夾,併在文件夾下寫上menu的佈局文件,nav_menu.xml 4.由於我們還使用了toobar,因此在menu文件夾下同樣寫上toolbar.xml 5.lay ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...