在 Next.js 中透過動態匯入功能分割程式碼

如何運用程式碼分割和智慧載入策略來加快 Next.js 應用程式的速度。

米莉卡.米哈吉利亞 (Milica Mihajlija)
Milica Mihajlija

您會學到什麼?

本文會說明不同類型的程式碼分割,以及如何使用動態匯入功能加快 Next.js 應用程式的速度。

依據路徑和元件的程式碼分割

根據預設,Next.js 會將您的 JavaScript 針對每條路徑分成不同的區塊。使用者載入應用程式時,Next.js 只會傳送初始路徑所需的程式碼。使用者在瀏覽應用程式時,會擷取與其他路徑相關聯的區塊。路徑型程式碼分割功能可盡量減少一次需要剖析和編譯的指令碼,進而加快網頁載入時間。

雖然路徑型程式碼分割是不錯的預設設定,但您也可以在元件層級使用程式碼分割功能,進一步改善載入程序。如果應用程式有大型元件,建議您將元件分成不同的區塊。這樣一來,任何非重要元件,或只會在特定使用者互動 (例如點選按鈕) 顯示的大型元件都可以延遲載入。

Next.js 支援動態 import(),可讓您動態匯入 JavaScript 模組 (包括 React 元件),並將每次匯入作業以個別區塊的形式載入。如此一來,您就可以使用元件層級的程式碼分割功能,並控制資源的載入作業,讓使用者只下載自己在網站瀏覽區塊所需的程式碼。在 Next.js 中,這些元件預設為伺服器端轉譯 (SSR)

動態匯入功能應用實例

本文提供範例應用程式的多個版本,其中包含一個簡單的頁面,以及一個按鈕。點選按鈕後,就會看到可愛小狗。在瀏覽每個應用程式版本的過程中,您將瞭解動態匯入與靜態匯入的差異,以及如何使用動態匯入。

小狗在第一個應用程式版本中,則位於 components/Puppy.js 中。為了在網頁上顯示小狗,應用程式會使用靜態匯入陳述式將 Puppy 元件匯入 index.js

import Puppy from "../components/Puppy";

如要瞭解 Next.js 如何封裝應用程式,請在開發人員工具中查看網路追蹤記錄:

  1. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕

  2. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。

  3. 按一下 [網路] 分頁標籤。

  4. 勾選「停用快取」核取方塊。

  5. 重新載入網頁。

載入頁面時,index.js 會隨附所有必要程式碼,包括 Puppy.js 元件:

開發人員工具「Network」分頁顯示六個 JavaScript 檔案:index.js、app.js、webpack.js、main.js、0.js 和 dll (動態連結程式庫) 檔案。

當您按下「Click me」按鈕時,系統只會將小小 JPEG 的要求新增至「Network」分頁:

點選按鈕後,開發人員工具「Network」分頁,顯示相同的 6 個 JavaScript 檔案和一張圖片。

這個做法的缺點是,即使使用者並未點選按鈕來查看小狗按鈕,還是必須載入 Puppy 元件,因為隨附元件已包含在 index.js 中。在這個簡單的例子中,這雖然不算大,但在實際應用程式中,通常只有在必要時載入大型元件時,通常可以大幅改善。

現在來看看應用程式的第二個版本,其中靜態匯入將以動態匯入取代。Next.js 包含 next/dynamic,可讓您為 Next.js 的任何元件使用動態匯入:

import Puppy from "../components/Puppy";
import dynamic from "next/dynamic";

// ...

const Puppy = dynamic(import("../components/Puppy"));

按照第一個範例中的步驟檢查網路追蹤記錄。

首次載入應用程式時,系統只會下載 index.js。由於這次沒有 Puppy 元件的程式碼,因此這次縮減了 0.5 KB (從 37.9 KB 減少到 37.4 KB):

開發人員工具網路顯示相同的 6 個 JavaScript 檔案,但 index.js 現在更小 0.5 KB。

Puppy 元件現在位於獨立的區塊 1.js 中,只有在您按下按鈕時才會載入:

點選按鈕後,開發人員工具「Network」分頁,顯示在檔案清單底部新增的其他 1.js 檔案和圖片。

在實際應用程式中,元件通常較大,延遲載入元件可能會減少數百 KB 的酬載。

具備自訂載入指標的動態匯入功能

延遲載入資源時,建議提供載入指標,以免發生延遲。在 Next.js 中,您可以在 dynamic() 函式中額外提供引數,以完成此操作:

const Puppy = dynamic(() => import("../components/Puppy"), {
  loading: () => <p>Loading...</p>
});

如要查看載入指標實際運作情形,請在開發人員工具中模擬網路連線速度緩慢的情形:

  1. 如要預覽網站,請按下「查看應用程式」,然後按下「全螢幕」圖示 全螢幕

  2. 按下 `Control+Shift+J 鍵 (在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。

  3. 按一下 [網路] 分頁標籤。

  4. 勾選「停用快取」核取方塊。

  5. 在「Throttling」下拉式清單中選取「Fast 3G」

  6. 按下「按這裡」按鈕。

現在,當您點選按鈕時,需要一段時間才能載入元件,應用程式同時會顯示「載入中...」訊息。

顯示文字的深色畫面

不含 SSR 的動態匯入

如果只需要在用戶端算繪元件 (例如即時通訊小工具),可以將 ssr 選項設為 false

const Puppy = dynamic(() => import("../components/Puppy"), {
  ssr: false,
});

結語

Next.js 支援動態匯入功能,可提供元件層級的程式碼分割功能,讓您盡可能減少 JavaScript 酬載,並縮短應用程式載入時間。根據預設,所有元件都會在伺服器端轉譯,您可以視需要停用這個選項。