Next.js中的路由预取
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
页面链接到margherita.js
了 <Link>
:
使用Chrome DevTools验证是否margherita.js
已预取:
-
要预览站点,请按View App。然后按 全屏
-
按
Control+Shift+J
(或Command+Option+J
在Mac上)按打开DevTools。 -
单击网络选项卡。
-
选择禁用缓存复选框。
-
重新加载页面。
加载时index.js
,“网络”选项卡也显示margherita.js
已下载:
如何自动预取工作
Next.js仅预取出现在视口中的链接,并使用Intersection Observer API 来检测它们。当网络连接缓慢或用户Save-Data
打开电源时,它还会禁用预取 。基于这些检查,Next.js动态注入<link rel="preload">
标签以下载组件以进行后续导航。
Next.js仅获取JavaScript;它不执行它。这样,它不会下载预取页面可能要求的任何其他内容,直到您访问该链接为止。
警告: Glitch示例在生产模式下运行,因为预取取决于浏览条件,并且仅在优化的生产版本中启用。要切换到开发模式,请查看README.md
Glitch示例中的。
由于<link rel="preload">
请求的资源具有高优先级,因此浏览器希望立即使用它们,这会触发控制台警告。优先级提示将很快在Chrome中可用,这将使Next.js可以为不需要立即使用的资源指示较低的优先级<link rel="preload" importance="low">
。
避免不必要的预取
为了避免下载不必要的内容,您可以禁用预取通过设置很少访问的网页prefetch
上的属性<Link>
来false
:
<Link href="/pineapple-pizza" prefetch={false}>
<a>Pineapple pizza</a>
</Link>
在第二个示例应用程序中,index.js
页面具有<Link>
, pineapple-pizza.js
其prefetch
设置为false
:
要检查网络活动,请按照第一个示例中的步骤进行操作。加载时index.js
,“ DevTools网络”选项卡显示margherita.js
已下载,但pineapple-pizza.js
不是:
与自定义路由预取
该<Link>
组件适用于大多数用例,但是您也可以构建自己的组件来进行路由。Next.js通过中提供的路由器API使您轻松实现这一点next/router
。如果要在导航到新路线之前做某事(例如,提交表单),则可以在自定义路线代码中进行定义。
使用自定义组件进行路由时,也可以向其中添加预取。要在路由代码中实现预取,请使用中的prefetch
方法 useRouter
。
看看components/MyLink.js
这个示例应用程序:
预取是在useEffect
挂钩内完成的 。如果将的 prefetch
属性<MyLink>
设置为true
,则在呈现该href
属性时指定的路由将 被预取<MyLink>
:
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
on/margherita
和false
on /pineapple-pizza
。
<MyLink href="/margherita" title="Margherita" prefetch={true} />
<MyLink href="/pineapple-pizza" title="Pineapple pizza" prefetch={false} />
加载时index.js
,“网络”选项卡显示margherita.js
已下载,pineapple-pizza.js
而不是:
当您单击任一链接时,控制台将记录“与Next.js玩得开心”。并导航到新路线:
结论
使用时<Link>
,Next.js会自动预取呈现链接页面所需的JavaScript,这将使导航到新页面的速度更快。如果使用的是自定义路由,则可以使用Next.js路由器API来实现自己的预取。通过禁用很少访问的页面的预取,避免不必要地下载内容。