在 Next.js 中使用預先擷取路徑

Next.js 如何透過預先擷取及自訂路徑功能,加快導航速度。

Milica Mihajlija
Milica Mihajlija

您會學到什麼?

本文將介紹 Next.js 中的轉送功能如何運作、如何進行最佳化處理,以及如何根據自身需求自訂。

Next.js 中,您不需要手動設定轉送功能。 Next.js 採用檔案系統式轉送功能,讓您只需建立檔案和資料夾 在 ./pages/ 目錄中:

含有三個檔案的網頁目錄螢幕截圖:index.js、margherita.js 和 Pineapple-pizza.js。

如要連結至不同的頁面,請使用 <Link> 元件,方法與 使用有效的舊 <a> 元素:

<Link href="/margherita">
  <a>Margherita</a>
</Link>

使用 <Link> 元件進行導覽時,Next.js 會稍微執行一些操作 為您提供更多一般而言,當您點選連結時,網頁就會下載,但 Next.js 會自動預先擷取轉譯網頁所需的 JavaScript。

載入內含幾個連結的網頁時,有可能在您追蹤之後 連結,代表系統已擷取其背後的元件。這可以 加快瀏覽新頁面的速度,讓應用程式做出回應。

在下方的範例應用程式中,index.js 頁面會連結至 margherita.js<Link>

使用 Chrome 開發人員工具驗證 margherita.js 是否已預先擷取: 1.如要預覽網站,請按下「查看應用程式」。然後按下 全螢幕 全螢幕

  1. 按下 Control+Shift+J 鍵 (或在 Mac 上為 Command+Option+J 鍵) 開啟開發人員工具。
  2. 按一下 [網路] 分頁標籤。

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

  4. 重新載入網頁。

載入 index.js 時,「Network」分頁會顯示 margherita.js 下載次數:

開發人員工具「Network」分頁,醒目顯示 margherita.js。

自動預先擷取的運作方式

Next.js 只會預先擷取可視區域中顯示的連結,並使用 Intersection Observer API 偵測這些資料網路連線速度緩慢時,此功能也會停用預先擷取功能 或是使用者 Save-Data敬上 已開啟。Next.js 會根據這些檢查結果動態插入 <link rel="preload"> 標記,以便下載 後續瀏覽動作

Next.js 只會「擷取」 JavaScript;但不會執行這樣一來 下載任何預先擷取網頁可能會要求的任何其他內容,直到你造訪 。

避免不必要的預先擷取

如要避免下載不必要的內容,您可以針對極少數情況停用預先擷取功能 將 <Link>prefetch 屬性設為 false,即可追蹤造訪的網頁:

<Link href="/pineapple-pizza" prefetch={false}>
  <a>Pineapple pizza</a>
</Link>

在第二個範例應用程式中,index.js 頁面有 <Link> prefetch 設為 falsepineapple-pizza.js

如要檢查網路活動,請按照第一個範例中的步驟進行。時間 載入 index.js,開發人員工具的「Network」分頁會顯示 margherita.js 已下載,但 pineapple-pizza.js 不會:

開發人員工具「Network」分頁,醒目顯示 margherita.js。

使用自訂路徑預先擷取

<Link> 元件適用於大多數用途,但您也可以建構 自行轉送Next.js 能讓您輕鬆使用 next/router 中可使用 Router API。 如果想要先執行特定操作 (例如提交表單),再前往新的活動 路徑則可在自訂路由程式碼中定義。

如果您將自訂元件用於轉送,也可在這類元件中新增預先擷取。 如要在轉送程式碼中導入預先擷取功能,請使用以下項目的 prefetch 方法: useRouter

在這個範例應用程式中查看 components/MyLink.js

預先擷取作業是在 useEffect 掛鉤。如果 <MyLink> 上的 prefetch 屬性設為 true,也就是 算繪 <MyLink> 時,系統會預先擷取 href 屬性:

useEffect(() => {
    if (prefetch) router.prefetch(href)
});

點選連結後,handleClick 即可完成轉送。收到訊息時 且 push 方法會前往新的路徑 在 href 中指定的:

const handleClick = e => {
    e.preventDefault();
    console.log("Having fun with Next.js.");
    router.push(href);
};

在這個範例應用程式中,index.js 頁麵包含 <MyLink>margherita.js,且 pineapple-pizza.js/margherita 上的 prefetch 屬性已設為 true 以及有關 /pineapple-pizzafalse 記錄。

<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza"  title="Pineapple pizza" prefetch={false} />

載入 index.js 時,「Network」分頁會顯示 margherita.js 已下載,但 pineapple-pizza.js 未:

開發人員工具「Network」分頁,醒目顯示 margherita.js。

無論點選哪一個連結,「Console」都會記錄「透過 Next.js 享受樂趣」。 並前往新路徑:

開發人員工具控制台顯示「透過 Next.js 享受樂趣」的訊息。

結論

使用 <Link> 時,Next.js 會自動預先擷取 。如果您是 使用自訂轉送功能,即可透過 Next.js 路由器 API 預先擷取。停用這項服務,避免下載不必要的內容 預先擷取極少造訪的網頁。