大家好 👋,我是 Moment,目前正在使用 Next.js、NestJS、Tiptap 和 LangGraph 开发 DocFlow。
DocFlow 是一个面向 AI 全栈场景的协同文档平台,主要围绕富文本编辑、实时协作和 AI 工作流展开。
如果你对 AI 全栈开发、Tiptap、LangGraph 或协同文档感兴趣,欢迎添加我的微信
yunmz777一起交流。觉得项目还不错的话,也欢迎给 DocFlow 点个 star ⭐
过去讨论 Next.js 更新,关注点多半落在构建速度、渲染性能、缓存策略和 React API 上。
到了 16.3,框架的边界明显扩大了。Instant Navigations 发布公告 把用户侧体验往前推了一步,AI Improvements 说明 则开始系统性地适配 Claude Code、Cursor、Codex 等 Coding Agent。
一条主线面向终端用户:让服务端驱动的页面拥有接近 SPA 的即时反馈。
另一条主线面向开发者和 Agent:让它们能读取正确版本的文档、修改代码、检查运行状态并验证结果。
截至 2026 年 6 月 29 日,Next.js 16.3 仍处于 Preview 阶段,可通过 next@preview 提前测试。正式版发布前,部分 API 和配置仍可能调整。
服务端导航快不起来的根因
服务端组件可以直接访问数据库、内部服务和敏感资源,也能减少客户端 JavaScript。但它一直有一个明显短板:页面导航往往要等服务端读完数据,用户才会看到页面变化。
传统服务端导航必须等完整响应返回,用户点击后会经历一段明显的空白等待。SPA 则不同,点击后目标页面结构会立刻出现,数据再逐步补齐。
Instant Navigations 说明 把导航慢拆成两个独立问题:客户端到服务端的网络往返,以及服务端生成完整响应的耗时。前者靠预取解决,后者靠 Stream 和 Cache 让服务端不再阻塞整页输出。
Instant Navigations 要做的,是把 SPA 的即时反馈和服务端渲染的数据能力合在一起:继续用 Server Components 和服务端数据,先显示目标页面中已经确定的结构,再流式补全动态数据。它不是把 Next.js 重新变回客户端 SPA。
导航慢通常卡在两个位置,网络往返让点击后迟迟等不到第一帧,服务端阻塞则让整页必须算完才返回。Instant Navigations 分别用 Partial Prefetching 和 Stream、Cache 处理这两段空白。
只优化其中一个间隙,点击后仍可能白屏或重复预取。两个间隙都处理,导航才会真正接近 SPA 的即时感。
点击链接后先进入目标页面
要使用 Instant Navigations,需要先启用 Cache Components:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
cacheComponents: true,
};
export default nextConfig;
官方说明 把这一开关视为回归 dynamic by default 的新行为入口,未来 major 版本里很可能成为默认配置。启用后,页面里每一处服务端 await 都必须明确选择 Stream、Cache 或 Block,框架不再替你隐式决定。
Stream 先显示结构再加载数据
可以稍后出现的内容,用 <Suspense> 包起来:
import { Suspense } from "react";
export default function DashboardPage() {
return (
<main>
<h1>控制台</h1>
<Suspense fallback={<DashboardSkeleton />}>
<DashboardData />
</Suspense>
</main>
);
}
async function DashboardData() {
const data = await getDashboardData();
return <DashboardContent data={data} />;
}
用户进入页面后,可以先看到标题、布局和骨架,等服务端数据准备好,再继续流式返回真实内容。这种方式适合统计数据、搜索结果、推荐内容和消息列表。
Cache 复用已经生成的内容
允许跨请求复用的数据,可以用 'use cache':
import { cacheLife } from "next/cache";
async function ArticleHeader({ id }: { id: string }) {
"use cache";
cacheLife("minutes");
const article = await getArticle(id);
return <h1>{article.title}</h1>;
}
缓存适合文章信息、商品基础资料、公共导航和变化不频繁的配置。用户进入页面时,可以直接复用已有内容,不必等服务端重新跑完全部计算。
Block 等待完整结果
有些页面既不适合显示骨架,也不该走缓存。例如博客正文必须完整返回、不允许先出现 Loading 壳时,可以明确关闭即时导航:
export const instant = false;
这类页面仍会等待服务端返回完整结果,开发环境里对应的 Instant Insight 也会消失。
Stream、Cache 和 Block 不是优劣关系,而是三种不同的产品选择。官方把它们描述成把异步操作变成可即时呈现的内容:Stream 用占位 UI 换时间,Cache 用已有结果换时间,Block 则主动接受等待。
启用 Cache Components 后,每个服务端 await 都必须落到这三种策略之一,选错会直接体现在 Instant Insight 里。
可以稍后出现的内容用 Stream,可以重复利用的内容用 Cache,必须完整返回的页面用 Block。Next.js 过去更倾向自动判断静态和动态渲染,16.3 则进一步强调显式表达数据和页面的行为。
Instant Insights 帮你看清导航为何被阻塞
启用 Cache Components 后,如果一个异步操作既没有缓存,也没有放进 Suspense,Next.js 会在开发环境里给出 Instant Insight,并把慢导航视为开发期错误。
它不仅指出哪里阻塞了导航,还会给出三种带标签的修复方向:
[stream]用<Suspense>做流式渲染[cache]用'use cache'复用内容[block]用instant = false明确等待结果
过去的错误通常只说明某段代码无法预渲染。现在的错误开始解释它对页面体验产生了什么影响,以及应该怎么改。AI Improvements 说明 还为每条规则准备了独立文档页,Overlay 和终端里都带有 Copy as prompt 按钮,可以把问题、代码位置、修复步骤和验证要求打包成可直接交给 Coding Agent 的任务。
导航体验的问题,开始从只能人眼排查,变成可以交给 Agent 处理的结构化任务。
Partial Prefetching 不再重复预取完整页面
Stream 和 Cache 解决的是服务端生成响应时的阻塞。要让点击后的第一帧也足够快,客户端还得提前拿到可复用的页面结构。
16.2 之前,Next.js 会对视口内每个 <Link> 各发一次预取请求。聊天侧边栏里如果有 20 个 /chat/[id] 链接,就会触发 20 次几乎相同的预取。官方也承认这在 Network 面板里看起来相当浪费。
Partial Prefetching 借鉴 SPA 按路由拆分代码的思路:不再为每个动态链接预取整页,而是为每个 distinct route 预取一份可复用的 shell,并在客户端 session 内缓存。假设聊天应用里存在大量动态链接:
/chat/1
/chat/2
/chat/3
/chat/4
这些页面参数不同,但布局基本相同。真正可以复用的是侧边栏、顶部导航、消息容器、输入框和加载骨架,而不是每个会话的完整数据。
Partial Prefetching 的核心变化,是按 distinct route 预取一份 Shell,而不是为每个动态链接重复拉整页。
启用方式如下:
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
cacheComponents: true,
partialPrefetching: true,
};
export default nextConfig;
Shell 给出即时导航的基线。如果某个链接还需要更深一层的预取,比如聊天页头部也要秒开,可以在 <Link prefetch={true}> 上按需开启 per-link 预取,但框架仍只会预渲染到同步可用或 'use cache' 标记的内容,不会回到整页 deep prefetch 的老路。
用户点击任意会话时,客户端先立即显示缓存中的 shell,再加载当前会话的数据。这能减少重复请求,也能降低大量动态链接带来的预取压力,特别适合聊天应用、管理后台、协同文档、工作流平台和商品列表。
页面 shell 正在成为新的性能边界
过去我们经常把页面简单分成静态页面和动态页面。在 Cache Components、Suspense 和 Partial Prefetching 下,一个页面可以同时包含提前生成的页面结构、可以复用的缓存内容、必须实时获取的动态数据,以及只能在客户端运行的交互状态。
Next.js 不再要求整页采用同一种渲染策略,而是允许不同区域拥有不同的加载方式。文档编辑器的 shell 可能是侧边栏、工具栏和编辑区框架;聊天应用的 shell 可能是会话布局、输入框和消息骨架;工作流平台的 shell 可能是节点画布、操作栏和属性面板。
同一个页面里,Shell、Cache 和 Stream 往往同时存在,各自负责不同区域的加载节奏。
Shell 决定点击后第一帧能看到什么,Cache 和 Stream 决定哪些区域之后如何继续补齐。如果整页都被一个顶层 Suspense 包裹,导航虽然没被阻塞,用户看到的也可能仍然只是一整块 Loading,这正是后面 Navigation Inspector 要抓的典型问题。
Navigation Inspector 让导航体验可测
16.3 增加了 Navigation Inspector,可以直接观察一次导航中哪些内容已经进入预取 shell、哪些内容点击后可以立即显示、哪些部分仍要等待服务端,以及 Suspense 边界是否放得过高。
它会在每次导航时先暂停在 shell 状态,让你看清预取结果,再点 Resume 看完整页面。实际预取行为只在 production 模式生效,开发期主要靠 Inspector 和 Instant Insights 定位问题。
Next.js 还为 Playwright 提供了 instant() 测试能力:
import { expect, test } from "@playwright/test";
import { instant } from "@next/playwright";
test("商品页可以立即显示页面结构", async ({ page }) => {
await page.goto("/products/shoes");
await instant(page, async () => {
await page.click('a[href="/products/hats"]');
await expect(page.locator("h1")).toContainText("棒球帽");
await expect(page.getByText("正在检查库存")).toBeVisible();
});
await expect(page.getByText("库存 12 件")).toBeVisible();
});
instant() 断言的是不等待网络时页面上应该已经可见的内容,完整数据则放在回调外继续等待。过去自动化测试通常只验证页面最终是否正确,现在还可以验证用户点击后,标题、布局、骨架和关键操作区是否立即出现。导航体验开始从主观感受,变成可以进入 CI 的回归指标。
Agent 最大的坑是训练数据过期
Instant Navigations 面向用户,16.3 的另一组更新则面向 Coding Agent。
Agent 最常见的问题之一,是训练数据很容易过期。项目已经升级到 Next.js 16,Agent 仍可能生成旧版缓存写法、过时配置、错误的 params 用法,或者继续套用 Pages Router 的历史经验。
为了解决这个问题,Next.js 从 16.2 起把当前版本的文档放进 npm 包,16.3 里 next dev 还会自动向 AGENTS.md 写入版本指针。Agent 可以读取项目实际安装版本对应的本地资料,而不是只依赖模型训练时记住的知识。
AGENTS.md 让项目声明自己的开发规则
16.3 会利用 AGENTS.md 告诉 Coding Agent 当前项目使用哪个 Next.js 版本、修改前应该读取哪里的本地文档、不要直接采用训练数据中的旧 API,以及修改完成后应该如何验证。
next dev 检测到 Coding Agent 环境时,会自动插入带 BEGIN:nextjs-agent-rules 标记的规则块。项目自定义内容保留在标记外,也可通过 agentRules: false 关闭自动写入。
AGENTS.md 负责的是项目规则,不是替代官方文档。官方文档说明框架如何使用,AGENTS.md 则说明这个项目希望 Agent 怎样工作,包括目录边界、代码规范、禁止事项和验证要求。
Skills 把知识变成可执行流程
16.3 还提供了多个第一方 Skills:
next-dev-loop:执行修改、编译、启动、浏览器检查和继续修正next-cache-components-adoption:帮助旧项目逐步迁移到 Cache Componentsnext-cache-components-optimizer:优化页面 shell 和即时导航效果
安装方式如下:
npx skills add vercel/next.js --skill next-dev-loop
文档解决的是某个 API 应该怎么写,Skill 解决的是一个完整任务应该怎样完成。Agent 的工作方式正在从单步代码生成,转向带验证的完整闭环。
代码生成只是其中一步,运行和验证才构成完整闭环。未通过验证时,流程会回到修改代码继续修正,而不是把生成结果直接当成交付物。
MCP、Agent Browser 和 Playwright 各司其职
Next.js 没有把所有能力塞进一个 MCP Server,而是逐渐形成了清晰的分层:
-
本地文档负责版本知识
-
AGENTS.md负责项目规则 -
Skills 负责多步骤工作流
-
DevTools MCP 负责运行时诊断
-
Agent Browser 负责浏览器和 React 状态检查
-
Playwright 负责回归测试
16.3 的 DevTools MCP 移除了内置知识库工具,新增
get_compilation_issues和compile_route,让 Agent 不必每次改动都跑完整next build。Agent Browser 合并了 16.2 的next-browser,并支持react tree、react inspect和react suspense等 React DevTools 能力。Playwright 则负责证明修改后的页面行为符合预期。
这种分层比让一个 MCP 同时负责知识查询、代码修改、浏览器操作和高风险命令更合理,也更容易控制权限。
Adapter API 处理部署边界
除了渲染和 AI Coding,Next.js 16 系列还在推进 Adapter API。Across Platforms 说明 里提到,构建完成后 Next.js 可以输出一份类型化、带版本的应用描述,包括路由、静态资源、预渲染结果、运行时目标和缓存规则。
不同部署平台可以依据这份公开契约,把 Next.js 应用部署到自己的 CDN、Serverless、Edge 或 Node.js 基础设施。Next.js 正在同时建立三种边界:面向应用开发者的渲染和缓存模型、面向 Coding Agent 的知识和运行工具、面向部署平台的构建与运行契约。
现在是否应该升级
Next.js 16.3 目前仍是 Preview,不建议直接在核心生产项目里全面启用。可以先建测试分支:
git switch -c test-next-16-3
pnpm add next@preview
重点验证这些场景:
- App Router 页面导航
- Cache Components
- Suspense 边界
- 动态路由和
params <Link>预取- Server Actions
- 自托管部署
- Playwright 导航回归
普通内容网站这次更新的收益可能没那么明显。管理后台、聊天应用、协同文档、工作流平台和复杂 SaaS,则值得提前测试 Instant Navigations、Partial Prefetching 和 Agent 开发闭环。16.2 发布说明 里已经铺过一部分 Cache Components 的基础,16.3 更像是在此之上把导航体验和 Agent 工具链补齐。
Preview 阶段还有两个已知问题:Partial Prefetching 开启时,shell 内访问 params 会导致路由阻塞但不一定触发 Instant Insight;Instant Insights 在 Safari 开发环境里表现不稳定,建议用 Chrome 或 Firefox 调试。
总结
Next.js 16.3 表面上带来了 Instant Navigations、Partial Prefetching 和一系列 AI Coding 能力,更重要的是它正在改变框架边界。
页面渲染开始从静态或动态二选一,转向 shell、缓存内容和动态数据的组合。性能优化开始关注用户点击后能立即看到什么,而不只是页面最终多久加载完成。Coding Agent 也从代码生成工具,逐步变成能够读取文档、修改代码、启动应用、观察状态和验证结果的开发参与者。
16.3 真正值得关注的,不只是页面跳转更快了,而是它正在展示下一代 Web 框架的形态:框架不仅负责运行代码,也开始负责向开发者、Agent 和部署平台提供清晰、可执行、可观察和可验证的开发边界。这条路线不会只停留在 Next.js,NestJS、Prisma、Drizzle、Nuxt、SvelteKit 和其他生态,也会逐渐补齐版本文档、Agent 规则、结构化 CLI、MCP、Skills 和验证工具。