Next.js 如何通过路线预提取加快导航速度以及如何对其进行自定义。
您将学到什么?
在本文中,您将了解 Next.js 中的路由的工作原理、如何针对速度进行优化,以及如何对其进行自定义以最好地满足您的需求。
<Link>
组件
在 Next.js 中,您无需手动设置路由。
Next.js 使用基于文件系统的路由,让您可以直接创建文件和文件夹
./pages/
目录中:
![包含以下三个文件的 Pages 目录的屏幕截图:index.js、margherita.js 和 pineapple-pizza.js。](https://web.developers.google.cn/static/articles/route-prefetching-in-nextjs/image/screenshot-the-pages-dir-81addfb477754.png?authuser=5&hl=sl)
要链接到不同的网页,请使用
<Link>
组件,类似于在
请使用合适的旧 <a>
元素:
<Link href="/margherita">
<a>Margherita</a>
</Link>
当您使用 <Link>
组件进行导航时,Next.js 会执行一些操作
。通常,点击网页链接后就会下载该网页,但
Next.js 会自动预提取呈现网页所需的 JavaScript。
如果您加载的网页包含若干链接 表示链接后面的组件已被提取。这样可以改善 更快地导航到新页面,提高应用响应速度。
在下面的示例应用中,index.js
页面使用margherita.js
<Link>
:
使用 Chrome 开发者工具验证 margherita.js
是否已预提取:
1.如需预览网站,请按查看应用。然后按
全屏
。
- 按 `Ctrl+Shift+J`(在 Mac 上,按 `Command+Option+J`)打开开发者工具。
点击网络标签页。
选中停用缓存复选框。
重新加载页面。
加载 index.js
时,Network 标签页会显示 margherita.js
:
自动预提取的工作原理
Next.js 仅预提取显示在视口中的链接,并使用交集
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
设置为 false
的 pineapple-pizza.js
:
如需检查网络活动,请按照第一个示例中的步骤操作。时间
加载 index.js
后,开发者工具的 Network 标签页显示 margherita.js
已下载,但 pineapple-pizza.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
页面包含一个指向 margherita.js
的 <MyLink>
,
pineapple-pizza.js
。在 /margherita
上,prefetch
属性设置为 true
并前往 /pineapple-pizza
的false
。
<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza" title="Pineapple pizza" prefetch={false} />
加载 index.js
时,Network 标签页会显示 margherita.js
已下载,但 pineapple-pizza.js
不是:
当您点击任一链接时,控制台都会记录“ have fun with Next.js”。 然后导航到新路线:
总结
当您使用 <Link>
时,Next.js 会自动预提取加载
呈现链接的网页,这样可以更快地导航到新网页。如果您
使用自定义路由,您可以使用 Next.js Router API 来实现
自动预提取。您可以停用
针对很少访问的网页进行预提取。