Next.js 16.3: Instant Navigations
TL;DR · AI 摘要
Next.js 16.3 引入 Instant Navigations,使服务器驱动应用具备客户端单页应用的即时导航体验。
核心要点
- Next.js 16.3 引入 Instant Navigations,使服务器驱动应用具备客户端单页应用的即时导航体验。
- 启用 Cache Components 标志可使用新行为,未来将成为默认设置。
- 开发者可选择 Stream、Cache 或 Block 三种方式处理异步操作,提升导航速度。
结构提纲
按章节快速跳转。
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- Next.js 16.3: Instant Navigations
- Instant Navigations
- 解决服务器驱动应用导航慢的问题
- 使服务器驱动应用具备客户端单页应用的即时导航体验
- 启用 Cache Components
- 未来将成为默认设置
- Stream、Cache 或 Block
- 三种方式处理异步操作
金句 / Highlights
值得收藏与分享的关键句。
Instant Navigations 是一组工具,使 Next.js 应用具备客户端单页应用的即时导航体验。
启用 Cache Components 标志可使用新行为,未来将成为默认设置。
开发者可选择 Stream、Cache 或 Block 三种方式处理异步操作,提升导航速度。
Next.js 16.3:即时导航 | Next.js
返回博客
2026年6月24日,星期四
Next.js 16.3:即时导航
发布者
@acdlite
joshcstory
+8
Next.js 团队
12
成员
Next.js 16.3 即将发布,它包含大量改进:通过原生 Node.js 流实现更优的高负载渲染,本地开发时的更快启动时间,以及与基于代理的工作流程更深入的集成。
在接下来的几周中,我们将介绍这些功能,为稳定版本的发布做准备。但今天,我们想重点介绍一个新功能,我们称之为“即时导航”——一套工具,它将客户端驱动的单页应用(SPA)的响应性带给 Next.js,同时不牺牲其服务器驱动模型带来的优势。
让我们看看这个功能如何解决长期以来(且合理!)的批评,即服务器组件可能使应用感觉无响应。
即时导航
我们听到的关于 Next.js 应用最常见的烦恼之一是导航感觉很慢。
在服务器驱动的应用中,导航通常需要一次网络往返:
- 你点击一个链接。
- 没有任何反应。
- 然后服务器响应,下一页出现。
这并不一定是坏事,对于像报纸和博客这样的内容驱动网站,它可能工作得很好。但确实会让体验“感觉像网站”一样。它不够流畅。与客户端驱动的应用进行导航相比:
- 瞬间,你看到下一页的外壳(一些数据仍在加载)。
- 然后服务器响应,下一页完全展示出来。
这是许多开发者更倾向于创建单页应用(SPA)的一个常见原因。尽管服务器驱动的请求/响应范式有许多优势,但即时导航对于许多类型的应用来说仍然感觉更好。
我们正在解决这个问题
我们清楚地听到了你们的反馈。
在 Next.js 16.3 中,我们将推出新的可选行为,让你可以兼得两者的优势:具有即时导航的服务器驱动应用。你将获得服务器的全部优势,但导航却像单页应用一样即时。
让我们看看它是如何工作的。
首先,启用缓存组件
要尝试这些新行为,请启用缓存组件标志:
next.config.ts
import
type
{ NextConfig }
from
'next'
;
const
nextConfig
:
NextConfig
=
{
cacheComponents
:
true
,
// ...
};
export
default
nextConfig;在过去的一年中,我们一直在将 Next.js 简化回其根源:默认动态,没有隐藏或隐式的缓存。此标志启用了这些新行为,并将在 Next.js 的未来主要版本中成为默认设置。
流式传输、缓存或阻塞
现在,当一个路由在服务器上等待某些数据时,你将有几种选项可供选择:
新的即时洞察面板自动揭示缓慢的导航
这些选项意味着什么?
要使导航即时,你将一个异步操作“转换”为可以立即可用的内容:
- 使用 <Suspense> 流式传输。用户将立即看到加载状态(随后有更多 UI 内容流式传输进来)。
- 使用 'use cache' 缓存。用户将立即看到之前缓存的 UI(在请求之间重复使用)。
在上述两种情况下,导航对用户来说都会感觉像单页应用一样,即时且流畅。
然而,有时你可能希望将某个导航设置为服务器绑定。例如,一个博客可能选择永远不为文章显示加载外壳。对于这些情况,你可以告诉 Next.js 你希望这个导航进行 Block 操作:
// 在 page.tsx 或 layout.jsx 中
export
const
instant
=
false
;然后错误对话框就会消失。
请注意,这将让你掌握控制权。如果你希望你的服务器驱动应用立即响应链接点击——而无需等待网络——那么你可以使用 Stream 或 Cache。如果你希望某些路由延迟导航,那么你可以使用 Block。
要了解更多关于 Instant Insights 如何与编码代理集成的信息,请阅读 Next.js 16.3: AI Improvements。
Agent 技能
如果你正在首次在现有应用中采用 Cache Components,我们已经为你准备了一个 Skill,你可以使用它让代理引导你完成整个过程。
复制提示:
保持导航的即时性
借助 Instant Insights,我们已将缓慢的导航视为开发中的错误。为了更容易在更改和重构后捕获对即时路由的回归,我们还为 Playwright 测试提供了即时测试助手:
import
{ expect
,
test }
from
'@playwright/test'
;
import
{ instant }
from
'@next/playwright'
;
test
(
'product title is available immediately'
,
async
({ page })
=>
{
await
page
.goto
(
'/products/shoes'
);
// 在不等待网络的情况下断言可见内容
await
instant
(page
,
async
()
=>
{
await
page
.click
(
'a[href="/products/hats"]'
);
await
expect
(
page
.locator
(
'h1'
))
.toContainText
(
'Baseball Cap'
);
await
expect
(
page
.getByText
(
'Checking inventory...'
))
.toBeVisible
();
});
await
expect
(
page
.getByText
(
'12 in stock'
))
.toBeVisible
();
});这使你(或你的代理)可以更细致地断言每次点击链接后必须立即可见的内容。
我们还在探索如何在构建过程中显示你在开发中看到的错误,这样任何对即时路由的回归都会在构建时被捕获。
重新思考预取
为了让导航真正即时(像单页应用一样),我们需要解决两个不同的问题:
- 客户端需要与服务器通信。如果它们之间的延迟较高,这可能会很慢。
- 此外,服务器需要生成响应。如果服务器代码运行缓慢,这可能会很慢。
通过 Streaming 或 Caching 响应,我们消除了第二个问题:服务器本身不会阻塞。但客户端和服务器之间仍然存在差距。Next.js 如何在用户点击时“立即”知道响应?
此前,Next.js 通过为视口中的每个链接发送预取请求来解决这个问题。如果你在生产模式下关注过网络标签页,你可能会注意到滚动时出现大量请求:
在 16.2 版本中,Next.js 为每个链接发送预取请求,即使这些链接指向相同的路由。
你们中的许多人告诉我们,这看起来很荒谬,坦白来说,我们也是这么认为的。
我们一直在思考单页应用是如何解决这个问题的。单页应用之所以能够立即响应每个导航,是因为它将显示下一页所需的所有代码打包并发送到客户端。它可能仍然需要更多数据——所以点击不会显示完整的页面——但足以显示页面的“外壳”。
因此,我们决定从单页应用中借用这个技巧。Next.js 不再为每个链接预取整个页面,而是为每个路由预取一个可重复使用的外壳(shell)。这些外壳将在客户端进行缓存,因此只会被获取一次。
例如,如果你的侧边栏中有二十个聊天链接,Next.js 以前会为每个链接发送一个单独的预取请求。然而,使用新的行为后,它将只为每个路由预取一次:一个用于 /chat/[id] 路由的外壳,一个用于 /dashboard 路由的外壳,依此类推。从概念上讲,这与单页应用通过按路由拆分代码来下载代码的方式类似。
在 16.3 版本中,Next.js 为每个路由预取一个加载外壳,并在多个链接之间重复使用它。
由于外壳可以在多个链接之间重复使用,它们也是离线导航的基础。在未来的版本中,我们将探讨预取的路由在网络短暂消失时仍能导航的可能性。
启用部分预取(Partial Prefetching)
要尝试这种新的预取行为,我们称之为“部分预取(Partial Prefetching)”,请在你的 Next.js 配置中启用:
import
type
{ NextConfig }
from
'next'
;
const
nextConfig
:
NextConfig
=
{
cacheComponents
:
true
,
partialPrefetching
:
true
,
// ...
};
export
default
nextConfig;与 cacheComponents 类似,我们计划在未来的主要版本中将 partialPrefetching 设置为默认行为。
检查加载外壳
为了更直观地展示这一点,我们为 Next.js DevTools 添加了一个新的导航检查器(Navigation Inspector)。
它允许你在外壳处暂停每次导航,以便查看任何路由的预取内容:
然后,当你点击“继续(Resume)”时,导航将显示完整的页面。这使你可以在开发过程中看到路由的哪些部分可以立即显示,哪些部分只能在网络请求后显示。
与之前一样,实际的预取功能仅在生产环境中启用。
预取外壳以外的内容
启用部分预取后,Next.js 默认预取的内容减少了。
不再为每个链接发送预取请求,Next.js 现在只会为视口内每个不同的路由预取一个可重复使用的外壳(如聊天页面一个,设置页面一个等),并在整个会话期间缓存这些外壳。
然而,有时候你可能希望预取的内容不仅仅是外壳。例如,你可能希望聊天页面的聊天标题可以“立即弹出”。为了启用每个链接的预取,你可以将 <Link prefetch={true}> 添加到一些链接中。
请注意,即使在这种情况下,Next.js 也不会尝试渲染整个路由到最深层。相反,它将渲染到同步可用或标记为“使用缓存”的内容。这意味着你不再需要在预取时做出“全有或全无”的选择。即时外壳为你提供了基准,然后使用 <Link prefetch={true}> 和“使用缓存”可以添加额外的每个链接预取,这可能包含更多内容。
为了保持成本保守,每个链接的预取仅限于构建时已知的内容。如果你不介意额外的服务器负载,可以通过 export const prefetch = 'allow-runtime' 将其扩展到运行时缓存的内容。
我们自己也在使用它
我们在发布此功能之前,已经在 v0 中采用了这些工具。v0 有很多丰富的客户端功能,但导航一直未能达到即时的感觉。
即时洞察(Instant Insights)指出了那些导航不即时的路由。一旦我们开始处理修复,导航速度有了显著提升:
v0 的导航时间(从点击到路由变更)
我们将在后续的帖子中分享我们最终确定的具体模式。我们仍在优化之前提到的预获取改进,因此我们预计这些数字会更接近零。
一个可以探索的演示
如果你想在一个更小的开源代码库中看到这些功能,Next Beats 是一个基于 Next.js 16.3 预览版构建的音乐播放器,其源代码在 GitHub 上。启用了 Cache Components,然后在每条路由上使用 Stream 和 Cache,因此每次导航都会落在一个真实的外壳上,而不是一个旋转器上。启用了部分预获取,因此每条路由在客户端上预获取一个可重用的外壳。结果是导航感觉是即时的,就像在单页应用中一样。
总结
总而言之,我们一直在努力让你的应用能够拥有类似单页应用的即时导航:
- 如果你使用 <Suspense> 进行 Stream 或使用 'use cache' 进行 Cache,那么导航到你的路由将是即时的。
- 如果你通过 export const instant = false 进行 Block,那么你将退出强制该路由的即时导航。
- Next.js 会自动为每个即时路由生成一个可重用的外壳,并且只预获取一次。
- 你可以使用 instant() 测试助手来避免回归,并使用导航检查器来可视化检查外壳。
- 你可以通过 <Link prefetch> 和 'use cache' 选择更深入的按链接预获取。
这些更改受 cacheComponents: true 和 partialPrefetching: true 标志的控制。
通过这些更改,我们正在使 Next.js 的首次点击导航体验与单页应用一样好,而无需放弃以服务器为中心的思维模型所带来的整体性能优势。
今天就来尝试
要亲自尝试即时导航,请今天安装 16.3 预览版:
npm
install
next@preview有关即时导航的更多信息,请查看预览文档。
我们非常乐意在 GitHub 上听到你的任何反馈,并且随着我们向一个完善稳定的版本迈进,我们将继续发布预览标签的更新。
已知问题
预览版中存在一些已知问题,我们正在积极解决这些问题。这些问题将在我们发布稳定版本之前得到修复。
- 在某些情况下,阻塞路由不会被报告为即时洞察。当启用部分预获取时,在外壳中访问参数会导致路由阻塞,但这不会被报告为即时洞察。导航检查器和 instant() 测试助手不受影响。
- Safari 中的即时洞察工具存在一些问题。在开发过程中,为了获得最佳效果,请使用 Chrome 或 Firefox。
请在此处查看这些问题何时得到解决。
反馈和社区
分享你的反馈,帮助塑造 Next.js 的未来:
- GitHub 讨论
- GitHub 问题
- Discord 社区