Next.js Blog

Next.js 16.3: Instant Navigations

8.5内容质量

TL;DR · AI 摘要

Next.js 16.3 引入 Instant Navigations,使服务器驱动应用具备客户端单页应用的即时导航体验。

核心要点

  • Next.js 16.3 引入 Instant Navigations,使服务器驱动应用具备客户端单页应用的即时导航体验。
  • 启用 Cache Components 标志可使用新行为,未来将成为默认设置。
  • 开发者可选择 Stream、Cache 或 Block 三种方式处理异步操作,提升导航速度。

结构提纲

按章节快速跳转。

  1. Next.js 16.3 即将发布,包含多项改进,其中 Instant Navigations 是重点新功能。

  2. Instant Navigations 是一组工具,使 Next.js 应用具备客户端单页应用的即时导航体验。

  3. 服务器驱动应用的导航通常需要网络往返,导致用户体验不流畅。

  4. 客户端驱动应用的导航可以即时显示页面壳,提升用户体验。

  5. 启用 Cache Components 标志可使用新行为,未来将成为默认设置。

  6. 开发者可选择 Stream、Cache 或 Block 三种方式处理异步操作,提升导航速度。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Next.js 16.3: Instant Navigations
    • Instant Navigations
      • 解决服务器驱动应用导航慢的问题
      • 使服务器驱动应用具备客户端单页应用的即时导航体验
    • 启用 Cache Components
      • 未来将成为默认设置
    • Stream、Cache 或 Block
      • 三种方式处理异步操作

金句 / Highlights

值得收藏与分享的关键句。

#Next.js#前端#性能优化#服务器组件
打开原文

Next.js 16.3:即时导航 | Next.js

返回博客

2026年6月24日,星期四

Next.js 16.3:即时导航

发布者

Andrew Clark

@acdlite

Josh Story

joshcstory

+8

Next.js 团队

12

成员

Next.js 16.3 即将发布,它包含大量改进:通过原生 Node.js 流实现更优的高负载渲染,本地开发时的更快启动时间,以及与基于代理的工作流程更深入的集成。

在接下来的几周中,我们将介绍这些功能,为稳定版本的发布做准备。但今天,我们想重点介绍一个新功能,我们称之为“即时导航”——一套工具,它将客户端驱动的单页应用(SPA)的响应性带给 Next.js,同时不牺牲其服务器驱动模型带来的优势。

让我们看看这个功能如何解决长期以来(且合理!)的批评,即服务器组件可能使应用感觉无响应。

即时导航

我们听到的关于 Next.js 应用最常见的烦恼之一是导航感觉很慢。

在服务器驱动的应用中,导航通常需要一次网络往返:

  • 你点击一个链接。
  • 没有任何反应。
  • 然后服务器响应,下一页出现。

这并不一定是坏事,对于像报纸和博客这样的内容驱动网站,它可能工作得很好。但确实会让体验“感觉像网站”一样。它不够流畅。与客户端驱动的应用进行导航相比:

  • 瞬间,你看到下一页的外壳(一些数据仍在加载)。
  • 然后服务器响应,下一页完全展示出来。

这是许多开发者更倾向于创建单页应用(SPA)的一个常见原因。尽管服务器驱动的请求/响应范式有许多优势,但即时导航对于许多类型的应用来说仍然感觉更好。

我们正在解决这个问题

我们清楚地听到了你们的反馈。

在 Next.js 16.3 中,我们将推出新的可选行为,让你可以兼得两者的优势:具有即时导航的服务器驱动应用。你将获得服务器的全部优势,但导航却像单页应用一样即时。

让我们看看它是如何工作的。

首先,启用缓存组件

要尝试这些新行为,请启用缓存组件标志:

next.config.ts

code
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 操作:

code
// 在 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 测试提供了即时测试助手:

code
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 配置中启用:

code
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 预览版:

code
npm
install
next@preview

有关即时导航的更多信息,请查看预览文档。

我们非常乐意在 GitHub 上听到你的任何反馈,并且随着我们向一个完善稳定的版本迈进,我们将继续发布预览标签的更新。

已知问题

预览版中存在一些已知问题,我们正在积极解决这些问题。这些问题将在我们发布稳定版本之前得到修复。

  • 在某些情况下,阻塞路由不会被报告为即时洞察。当启用部分预获取时,在外壳中访问参数会导致路由阻塞,但这不会被报告为即时洞察。导航检查器和 instant() 测试助手不受影响。
  • Safari 中的即时洞察工具存在一些问题。在开发过程中,为了获得最佳效果,请使用 Chrome 或 Firefox。

请在此处查看这些问题何时得到解决。

反馈和社区

分享你的反馈,帮助塑造 Next.js 的未来:

  • GitHub 讨论
  • GitHub 问题
  • Discord 社区