跳到正文
原文
Hacker News· jhuleatt·· 4 小时前精选AI 评分62

Next.js 16.4 发布:Cache Components 成为默认编程模型

Next.js 16.4

AI 导读

Next.js 16.4 发布,Cache Components 成为推荐默认编程模型,并内置 React 19.3。新增 ensureStatic、navigation() 和 prefetch() 等 API 用于精细控制页面的缓存与预取行为。

推荐理由

详细梳理 Cache Components 默认化与面向 AI 编码 agent 的升级工具链,开发者可据此规划升级路径。

正文 · AI 翻译

在 16.x 系列版本中,我们引入了一种新的编程模型,解决了你从一开始使用 App Router 时遇到的诸多痛点:

  • 它能带来快速的首屏加载,即使是针对个性化页面
  • 它让服务端渲染的应用拥有即时的客户端导航
  • 它让缓存变为显式启用、声明式且可组合的

这一新的编程模型被称为 Cache Components(缓存组件),它将成为 Next.js 17 的默认模型。

在此版本发布之前,我们没有全面推荐它,因为在某些场景下它无法实现与旧模型相同的成本与性能保证。

本版本包含了一些关键特性,弥补了这些差距。

从 Next.js 16.4 开始,我们很高兴地推荐 Cache Components 作为每个 Next.js 应用的最佳选择。

从今天起,所有使用 create-next-app 创建的新应用都将默认启用 Cache Components。新启动的项目可以毫无顾虑地享受新模型带来的所有好处。

对于已有应用,我们一直在投入开发更好的 agentic 工具,以帮助代码库迁移到新模型。新的 next upgrade --agent 命令为 agents 提供了针对特定版本的应用升级指引,而专门的 Skills 则帮助 agents 完成你采用 Cache Components 所需的任何重构工作。

Next.js 16.4 还为所有 Next.js 应用带来了多项开箱即用的改进,包括更低的开发态内存占用和磁盘体积、更短的编译时间、更小的生产产物包,以及 React 19.3。

下面是本版本完整概览,从 Cache Components 开始。

什么是 Cache Components?

Cache Components 是一套特性集合,允许你将组件树中的特定部分标记为可缓存。可以把 'use cache' 看作是组件级别的 Cache-Control HTTP header:

Next.js 在渲染页面时会解读这些 'use cache' 注解,在浏览器中缓存组件的 UI(在客户端导航期间),并可选地在服务器上缓存(在服务端渲染期间,或在构建时提前生成)。

这些可组合的注解让你在同一个页面内混用客户端缓存、完全可插拔的服务端缓存以及请求时渲染,并取代了之前 App Router 版本中隐式的缓存行为。

要了解有关 Cache Components 的更多信息,请阅读缓存指南。

Cache Components 的新特性

在本文中,我们用“Cache Components”来指代这一新的编程模型,你今天就可以在 Next.js 配置中启用两个 flag 来使用它:

Cache Components 最初发布时并不包含 Partial Prefetching,但现在它已被视为模型的一部分。你可以从 我们之前的版本发布文章了解更多关于 Partial Prefetching 的信息。

接下来是 16.4 中 Cache Components 的新特性。

确保 shells、prefetch 或页面是静态的

'use cache' 的标志性特性之一,是能够在同一个服务端响应中构建同时流式返回静态内容和动态内容的页面。

例如,你可以将当前用户的头像与一篇静态预渲染的博客文章组合在一起:

Next.js 可以从缓存(例如你应用的 /public 目录,或者 CDN)提供预渲染的博客文章,并在请求时渲染 UserAvatar,所有这些都通过同一个 HTTP 响应完成。

这种灵活性正是你能够构建具有复杂 UI 的应用,同时又不牺牲速度与动态性的原因。但有时你希望构建一个完全静态页面的应用。在这种情况下,一个动态组件可能会削弱原本已优化站点的性能或成本特性。

在 Next.js 16.4 中,ensureStatic 提供了一种简单的方式来确保某个路由的外壳、预取或完整导航是静态的。对于那些希望避免意外计算并降低服务器成本的应用来说,这可以防止动态组件悄悄混入路由。

例如,如果我们想强制让上面示例中的博客文章页面始终保持静态,并且永远不允许添加像 UserAvatar 这样的动态组件,我们可以为该路由添加 export const ensureStatic:

通过将 ensureStatic 设置为 "navigation",如果该页面中包含任何动态内容,Next.js 将使构建失败,从而确保对该路由的导航永远不会再在请求时渲染。

虽然 "navigation" 是最严格的形式,但你也可以将 ensureStatic 设置为 "prefetch"(以确保对该路由进行显式预取的链接仅获取静态内容)或 "shell"(以确保在该路由首次被发现时仅获取静态内容),如果你需要更细粒度的控制。

除了在单个页面上使用之外,你还可以将 ensureStatic 添加到布局中,以便对该布局内的所有页面应用相同的保证。例如,你可以将 ensureStatic = 'navigation' 添加到根布局,从而轻松确保你站点中每个页面的导航都是静态的:

然后,如果某些页面开始需要动态内容,你可以将其下推到嵌套布局中。

许多动态应用并不需要此功能,但对于像电子商务商店、营销页面或博客这样的已优化站点,ensureStatic 是一种防止不需要的请求时渲染的简单方法。

了解更多关于保持页面静态以及ensureStatic 配置的信息。

从预取中排除内容

预取是提升 Next.js 应用用户体验的一种强大方式。

通过使用 <Link prefetch> 或 useRouter().prefetch(),你可以在实际导航发生之前预渲染页面的缓存 UI,从而消除加载状态。

例如,让我们看一个简单的电子邮件应用。这里是一个收件箱,它会渲染指向每条消息的链接:

这是消息页面,它在首次加载消息线程时显示一个旋转加载图标,然后在浏览器中缓存以便后续访问:

虽然这让用户可以即时查看已经加载过的消息,但在首次打开消息时,他们仍然会看到加载旋转图标。

为了消除那种初始加载状态,我们可以为收件箱中的链接添加 prefetch:

现在,每条链接一旦变为可见就会预取消息页面上的所有缓存数据和 UI,这样在用户点击时它就已经准备就绪。

这通过消除应用中的加载状态带来了出色的用户体验,但也意味着每个可见链接都会提前加载整个消息线程——即使对于用户从未打开的消息也是如此。对于我们的电子邮件应用来说,这可能成本太高或给服务器带来太大负担。

与其仅仅关闭预取功能,更好的解决方案是只预取第一条消息,并推迟渲染线程中其余内容,直到用户实际进行导航。

在 Next.js 16.4 中,我们完全可以做到这一点。新的 navigation API 允许你在预取过程中排除加载缓存内容,有效地将其推迟到实际导航发生时。

在我们的示例中,我们可以将主题帖抽取到一个新组件中,并添加 await navigation() 以将其排除在预取之外:

现在,Message 页面在预取时只会渲染第一条消息,并等待完整的导航触发后再从数据库加载主题帖的其余内容并予以渲染。

除了 navigation() 之外,我们还新增了 prefetch(),你可以通过 await 来排除那些本会被纳入路由 shell 的已缓存内容。这样一来,这些内容的渲染将延迟到通过 <Link prefetch> 或 useRouter().prefetch() 进行显式预取时再进行。

这些 API 让你能够更精细地控制在不同导航阶段加载哪些数据,以便以最适合你应用的方式在急切渲染与延迟渲染之间取得平衡。

详细了解如何将工作延后到后续阶段,并参阅navigation 与 prefetch 的 API 参考。

新的 Agent 功能

我们正在持续投入 Agent 工具的开发,致力于把 Next.js 打造成一个能不断协助你保持应用安全与最新版本的系统。Next.js 16.4 在既有文档、Skills 以及验证工具的基础上,引入了 Agent 升级与反馈机制,帮助我们从你的实际开发方式中学习,并将改进反哺到你的应用中。

Agent 升级

next upgrade 新增的 --agent 选项能够让你的 Agent 自始至终完成应用升级。它会检查你当前安装的版本、选定目标发布版本,并为你的 Agent 准备好迁移指南、所需的 codemod 以及验证步骤。Agent 随后会应用此次更新、解决迁移引发的问题,并验证应用是否仍能正常运行。

你或你的 Agent 可以从应用所在目录中运行该命令:

使用 next@canary 即会运行最新的升级工具,即便你的应用仍停留在较旧版本的 Next.js 上也是如此。Agent 会获得最新的指引,从而将你的应用升级到最新发布版本。

保持版本最新只是第一步。为了帮助你持续保持最新,Next.js 16.4 引入了 experimental.agentUpgrade。当你或你的 Agent 运行 next dev 或 next build 时,一旦有相关的可用升级,Next.js 就会自动提醒你或你的 Agent,省去自行检查的麻烦。当你选择升级时,它会按照你配置的策略启动同样的 Agent 工作流。

你可以在 Next.js 配置中设置这些提醒:

  • 'security'(默认策略):在存在影响你当前已安装版本的已知漏洞时,提醒你进行升级。
  • 'latest':在有较新的主版本或次版本发布时予以提醒,并采用 latest 升级策略让你的应用保持最新。
  • false:关闭升级提醒。

我们还在为该标志开发一种未来的策略,帮助 Agent 以更地道、惯用的方式采纳新功能与编程模型变更,例如迁移到 Cache Components。现在,你就可以使用我们提供的、用于采用 Cache Components 以及 Partial Prefetching 的 Skills,让你的 Agent 协助你迁移到新模型。

详细了解借助编码 Agent 进行升级以及 agentUpgrade 配置。

Agent 反馈

在构建与升级应用的过程中,编码 Agent 经常会遇到框架错误、文档不够清晰或不得不采用变通方案的情况。新增的实验性 Agent 反馈工作流让它们能够撰写报告草稿,由你审阅后再选择是否发送给 Next.js 团队。

当你使用推荐的 create-next-app 设置创建新应用时,Agent 反馈默认处于开启状态。对于既有应用,你可以通过 Next.js 配置选择启用:

启用该功能后,next dev 会为你的 Agent 添加指令,让其在工作过程中收集潜在问题。任务完成后,Agent 会生成报告草稿,并在你的浏览器中打开以便审阅。

智能体会被指示省略源代码、日志、密钥和项目相关的细节。你可以编辑或丢弃每条报告,在你点击 Send feedback 之前,不会发送任何内容。

智能体反馈需要启用 Next.js Telemetry,且不会在 CI 中运行。

详细了解 智能体反馈 和 agentFeedback 配置。

面向所有应用的改进

更小的磁盘缓存体积

在 16.4 中,Turbopack 的磁盘缓存占用空间减少了 20%–25%,且无需更改配置。

缓存现在对占用大部分空间的数据使用 Zstandard 压缩,同时对元数据保留 LZ4 压缩,以维持快速的缓存查找速度。我们还改进了压缩整理流程,以更高效地清理过期数据。

惰性服务器 HMR

此前,更改一个共享服务器模块可能会触发在开发会话早期访问过(但已不再查看)的页面更新。

在 16.4 中,Turbopack 仅在请求需要时才编译并应用服务器更新。你正在查看的页面会随着你的编辑而更新,其他路由则等到再次被请求时才更新。这减少了你在应用中导航时产生的不必要后台工作。

Turbopack 共享运行时

Turbopack 现在将其运行时打包为一个跨路由共享的单个 chunk。这可以减少下载体积并提高缓存命中率。

阅读我们的 关于 chunking 的博客文章,详细了解此功能及其他 chunking 特性的更多信息。

更小的生产构建产物

在 16.4 中,Turbopack 在生产环境下生成更短的 CSS Module 类名,从而减小样式表以及引用它们的 HTML 和 JavaScript 的体积。开发环境保留较长的类名,以便于调试。

此外,Turbopack 现在使用 export mangling,通过缩短用于连接模块的内部 JavaScript export 名称,进一步减小 bundle 体积。

React 19.3

Next.js 16.4 内置 React 19.3,带来稳定的 View Transitions 和 Fragment Refs、新的 browser() API 等新特性。

阅读 React 19.3 发布公告,全面了解所有新特性。

新增实验性功能

Rust 版 React Compiler

React Compiler 会自动优化组件渲染,减少手动记忆化的需求。其实验性的 Rust 版本于 16.3 中引入,直接在 Next.js 中运行,而非通过 Babel。

在 16.4 中,新增的快速检查可以让它跳过不需要优化的文件。它还会在为服务器渲染构建 Client Components 时避免重复进行这些优化,从而减少编译你的应用所需的工作量。

16.4 还包含大量改进性能和正确性的编译器更新。Turbopack 团队贡献的内存分配改动使 React Compiler 的内存使用量减少了 30%,编译时间减少了 15%。

在你的 Next.js 配置中启用 React Compiler 并选择 Rust 版本:

详细了解 Rust 版 React Compiler 和 编译器性能改进。

磁盘缓存清理

在你编辑应用时,Next.js 可能会保留已不再需要的编译缓存工作。

在 16.4 中,一个实验性的垃圾回收器会从内存和磁盘缓存中移除这些未使用的内容,有助于在长时间的开发会话中降低资源占用。它还可以回收之前会话中的过期数据,例如已删除路由的编译缓存。

在你的 Next.js 配置中启用垃圾回收:

详细了解 turbopackGc。

惰性动态导入

动态导入可以让你延迟加载代码,但 Next.js 通常在开发期间会预先编译这些代码。

在 16.4 中,你可以选择仅在浏览器请求时才编译客户端的动态 import。这可以减少你尚未使用代码的初始编译工作量,例如在点击按钮后通过 import() 加载的库。

在你的 Next.js 配置中启用懒加载动态 import:

某些 next/dynamic import 仍会被立即编译。

了解更多关于 turbopackLazyDynamicImports 的信息。

Worker 线程

Turbopack 在独立的 Node.js 进程中运行诸如 Babel、PostCSS 和 webpack loader 等工具,这些进程通过 socket 与它通信。

使用 worker 线程后,这些工具会在单个进程中运行。这避免了独立进程和 socket 通信带来的开销,旨在降低开发和构建期间的内存与 CPU 占用。

在你的 Next.js 配置中启用 worker 线程:

在 Node.js 24.13.1 及更高版本上,由于一个 Node.js bug,Next.js 目前回退到子进程方案。

了解更多关于 turbopackPluginRuntimeStrategy 的信息。

额外的根目录与全局虚拟存储支持

Next.js 16.4 可以通过让你声明额外的根目录,来跟踪项目根目录之外的符号链接依赖。这让你能够更轻松地处理已链接的本地包,而无需扩展项目根目录以包含无关的目录。

这也支持与 pnpm、Bun、Nub 和 aube 的全局虚拟存储进行手动集成,这些存储跨项目和 worktree 共享已安装的依赖,以加快安装速度。自动集成计划在未来的版本中提供。

将包含你已链接依赖的目录添加到你的 Next.js 配置中:

对于 pnpm 的全局虚拟存储,将 pnpm store path 报告的存储目录添加为额外的根目录。

了解更多关于 additional roots 的信息。

Turbopack Bundle Analyzer

此版本为 Turbopack Bundle Analyzer 添加了重要功能。它现在可以:

  • 在新的路由摘要主页中高亮显示最大的客户端路由。
  • 提供新的表格视图,可按路由资源的主要贡献者快速排序。
  • 自动为你的多次分析创建快照,并可在你的应用变更时对 bundle 进行 diff 对比。
  • 区分关键渲染路径上的模块,并允许你在浏览时过滤掉异步依赖。

Bundle Analyzer 现在还包含一个实验性的 next-bundle-optimizer 智能体技能,可自动发现、诊断并优化你的应用所交付的 JavaScript 及其他资源的体积。

要使用该技能:

  • 将你的 Next.js 应用升级到 16.4。
  • 运行 npx skills add vercel/next.js --skill next-bundle-optimizer。
  • 在你选择的 AI 智能体中运行 /next-bundle-optimizer。

了解更多关于 Turbopack Bundle Analyzer 的信息。

反馈与社区

我们希望你能兴致勃勃地试用 Next.js 16.4!

让你的智能体使用我们的新 CLI 命令升级你的应用:

或自行升级:

也欢迎分享你的反馈,共同塑造 Next.js 的未来:

贡献者

Next.js 是数千名开发者共同努力的成果。此版本由以下人员为你呈现:

衷心感谢 @ztanner、@6iu8a、@swarnava、@lukahartwig、@uaoa、@orzazade、@Samiislam851、@jarrensj、@sampoder、@martinfrancois、@leejpsd、@alangenfeld、@aryabyte21、@kostyniuk、@Stanzilla、@bmorros94、@ranger-ross、@styfle、@itsybitsci、@Amusac、@anujbolewar、@spirosikmd、@mezotv、@Xanaado、@marcoshernanz、@mlekhi、@dacgray、@molebox、@jgruica、@zeeshan56656、@lazerg、@hamidrezahanafi、@marceloboeira、@DavidIlie、@fireairforce、@QingHeSite、@niketchandivade、@biubiukam、@seanbeirnes、@0ldh、@fabian-hiller、@hardfist、@bryan-ferry、@gdborton、@hammadxcm、@syedsohailhussain1、@kelvinampofo、@koenpunt、@mayur9210、@Jashnavi25、@akselipalmer、@m-kawafuji、@Janpot 和 @kyamaz99 的帮助!

来源:Hacker News · nextjs.org