Next.js 如何透過路徑預先載入加快導覽速度,以及如何自訂。
您會學到哪些內容?
本文將說明 Next.js 中的路由運作方式、如何針對速度進行最佳化,以及如何自訂以符合您的需求。
<Link>
元件
在 Next.js 中,您不必手動設定路由。Next.js 採用以檔案系統為基礎的路由,因此您只需在 ./pages/
目錄中建立檔案和資料夾即可:
如要連結至其他網頁,請使用 <Link>
元件,就像使用舊版 <a>
元素一樣:
<Link href="/margherita">
<a>Margherita</a>
</Link>
當您使用 <Link>
元件進行導覽時,Next.js 會為您執行更多操作。一般來說,您點選連結時會下載網頁,但 Next.js 會自動預先載入轉譯網頁所需的 JavaScript。
當您載入含有幾個連結的網頁時,當您點選連結時,連結後方的元件很可能已經擷取。這麼做可加快導覽至新頁面的速度,進而改善應用程式的回應速度。
在以下範例應用程式中,index.js
頁面會透過 <Link>
連結至 margherita.js
:
使用 Chrome 開發人員工具驗證 margherita.js
是否已預先載入:如要預覽網站,請按下「View App」。然後按下「Fullscreen」圖示 。
- 按下 `Control + Shift + J` 鍵 (在 Mac 上為 `Command + Option + J` 鍵) 開啟開發人員工具。
按一下 [網路] 分頁標籤。
勾選「Disable cache」核取方塊。
請重新載入頁面。
載入 index.js
時,「Network」分頁會顯示 margherita.js
也已下載:
自動預先擷取的運作方式
Next.js 只會預先載入在檢視區中顯示的連結,並使用 Intersection Observer API 偵測這些連結。當網路連線速度緩慢,或使用者已啟用 Save-Data
時,系統也會停用預先載入功能。根據這些檢查,Next.js 會動態插入 <link
rel="preload">
標記,下載後續導覽的元件。
Next.js 只會擷取 JavaScript,不會執行 JavaScript。如此一來,系統就不會在您點選連結之前,下載預先擷取的網頁可能要求的任何其他內容。
避免不必要的預先擷取
為避免下載不必要的內容,您可以將 <Link>
的 prefetch
屬性設為 false
,藉此停用較少造訪網頁的預先載入功能:
<Link href="/pineapple-pizza" prefetch={false}>
<a>Pineapple pizza</a>
</Link>
在第二個範例應用程式中,index.js
頁面有 <Link>
到 pineapple-pizza.js
,prefetch
設為 false
:
如要檢查網路活動,請按照第一個範例中的步驟操作。載入 index.js
時,開發人員工具的「網路」分頁會顯示 margherita.js
已下載,但 pineapple-pizza.js
未下載:
使用自訂路徑預先擷取
<Link>
元件適用於多數用途,但您也可以自行建構元件來進行路由。Next.js 提供 next/router
中的路由器 API,讓您輕鬆完成這項操作。如果您想在前往新路線前執行某些動作 (例如提交表單),可以在自訂轉送程式碼中定義這些動作。
使用自訂元件進行轉送時,也可以為這些元件新增預先載入功能。如要在路由程式碼中實作預先載入功能,請使用 useRouter
中的 prefetch
方法。
請查看以下應用程式範例中的 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
。prefetch
屬性已設為 true
(在 /margherita
上) 和 false
(在 /pineapple-pizza
上)。
<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza" title="Pineapple pizza" prefetch={false} />
載入 index.js
時,「Network」分頁會顯示 margherita.js
已下載,而 pineapple-pizza.js
則未下載:
當您點選任一連結時,控制台會記錄「Having fun with Next.js.」,並導覽至新路徑:
結論
使用 <Link>
時,Next.js 會自動預先擷取轉譯連結網頁所需的 JavaScript,讓您更快前往新網頁。如果您使用的是自訂轉送,可以使用 Next.js 路由器 API 自行實作預先載入功能。為不常造訪的網頁停用預先載入功能,避免不必要地下載內容。