2025年10月21日,星期二
Next.js 16
发布者在即将到来的Next.js Conf 2025之前,Next.js 16 现已可用。
本次发布对 Turbopack、缓存和 Next.js 架构进行了最新的改进。自上一个 Beta 版本以来,我们增加了多项新功能和改进:
- 缓存组件:使用部分预渲染(PPR)的新模型和使用缓存实现即时导航。
- Next.js Devtools MCP:模型上下文协议集成,改进了调试和工作流程。
- 代理:中间件被
proxy.ts替换,以明确网络边界。 - DX:改进了构建和开发请求的日志记录。
提醒一下,这些功能在之前的 Beta 版本中已经可用:
- Turbopack(稳定版):所有应用程序的默认打包器,实现高达 5-10 倍的快速刷新和 2-5 倍的构建速度。
- Turbopack 文件系统缓存(Beta 版):为大型应用程序提供更快的启动和编译时间。
- React 编译器支持(稳定版):内置集成,实现自动记忆化。
- 构建适配器 API(Alpha 版):创建自定义适配器以修改构建过程。
- 增强路由:通过布局去重和增量预取优化导航和预取。
- 改进的缓存 API:新的
updateTag()和改进的revalidateTag()。 - React 19.2:视图转换、
useEffectEvent()、<Activity/>。 - 重大更改:异步参数、
next/image默认值等。
升级到 Next.js 16
# Use the automated upgrade CLI
npx @next/codemod@canary upgrade latest
# ...or upgrade manually
npm install next@latest react@latest react-dom@latest
# ...or start a new project
npx create-next-app@latest如果 codemod 无法完全迁移您的代码,请阅读升级指南。
新功能和改进
缓存组件
缓存组件是一组新功能,旨在使 Next.js 中的缓存更明确、更灵活。它们围绕新的 "use cache" 指令展开,该指令可用于缓存页面、组件和函数,并利用编译器在使用时自动生成缓存键。
与 App Router 早期版本中隐式缓存不同,缓存组件中的缓存完全是可选的。任何页面、布局或 API 路由中的所有动态代码在默认情况下都会在请求时执行,这使得 Next.js 的开箱即用体验更好地与开发人员对全栈应用程序框架的期望保持一致。
缓存组件也完善了部分预渲染 (PPR) 的概念,该功能于 2023 年首次引入。在 PPR 之前,Next.js 必须选择将每个 URL 静态或动态渲染;没有中间地带。PPR 消除了这种二分法,并允许开发人员将其静态页面的部分内容选择动态渲染(通过 Suspense),而不会牺牲完全静态页面的快速初始加载。
您可以在 next.config.ts 文件中启用缓存组件。
const nextConfig = {
cacheComponents: true,
};
export default nextConfig;我们将在 10 月 22 日的Next.js Conf 2025上分享更多关于缓存组件及其使用方法,我们将在未来几周内在我们的博客和文档中分享更多内容。
注意:正如之前在 Beta 版本中宣布的那样,以前的实验性
experimental.ppr标志和配置选项已删除,取而代之的是缓存组件配置。
在此处文档中了解更多信息。
Next.js Devtools MCP
Next.js 16 引入了 Next.js DevTools MCP,这是一种模型上下文协议集成,可用于 AI 辅助调试,并提供对应用程序的上下文洞察。
Next.js DevTools MCP 为 AI 代理提供:
- Next.js 知识:路由、缓存和渲染行为。
- 统一日志:无需切换上下文即可查看浏览器和服务器日志。
- 自动错误访问:无需手动复制即可获得详细的堆栈跟踪。
- 页面感知:对活动路由的上下文理解。
这使得 AI 代理可以直接在您的开发工作流程中诊断问题、解释行为并建议修复方案。
在此处文档中了解更多信息。
proxy.ts(原 middleware.ts)
proxy.ts 替换了 middleware.ts,并明确了应用程序的网络边界。proxy.ts 在 Node.js 运行时上运行。
- 操作方式:将
middleware.ts重命名为proxy.ts,并将导出的函数重命名为proxy。逻辑保持不变。 - 原因:更清晰的命名和用于请求拦截的单一、可预测的运行时。
export default function proxy(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url));
}注意:
middleware.ts文件仍可用于 Edge 运行时用例,但它已弃用,并将在未来版本中删除。
在此处文档中了解更多信息。
日志记录改进
在 Next.js 16 中,开发请求日志得到了扩展,显示了时间花费在哪里。
- 编译:路由和编译
- 渲染:运行您的代码和 React 渲染

构建也得到了扩展,显示了时间花费在哪里。构建过程中的每个步骤现在都显示了完成所需的时间。
▲ Next.js 16 (Turbopack)
✓ Compiled successfully in 615ms
✓ Finished TypeScript in 1114ms
✓ Collecting page data in 208ms
✓ Generating static pages in 239ms
✓ Finalizing page optimization in 5ms以下功能已在 Beta 版本中发布
开发者体验
Turbopack(稳定版)
Turbopack 在开发和生产构建方面均已达到稳定,现已成为所有新 Next.js 项目的默认打包器。自今年夏天发布 Beta 版以来,采用率迅速增长:Next.js 15.3+ 上超过 50% 的开发会话和 20% 的生产构建已在使用 Turbopack。
使用 Turbopack,您可以期待:
- 生产构建速度提高 2-5 倍
- 快速刷新速度提高多达 10 倍
我们将 Turbopack 作为默认设置,将这些性能提升带给每个 Next.js 开发人员,无需任何配置。对于使用自定义 webpack 设置的应用程序,您可以通过运行以下命令继续使用 webpack:
next dev --webpack
next build --webpackTurbopack 文件系统缓存(测试版)
Turbopack 现在支持开发中的文件系统缓存,在运行之间将编译器工件存储在磁盘上,从而显著加快重启时的编译时间,尤其是在大型项目中。
在您的配置中启用文件系统缓存
const nextConfig = {
experimental: {
turbopackFileSystemCacheForDev: true,
},
};
export default nextConfig;所有 Vercel 内部应用程序都在使用此功能,我们注意到大型存储库的开发人员生产力显著提高。
我们期待您在迭代文件系统缓存时提供反馈。请尝试使用并分享您的经验。
简化 create-next-app
create-next-app 经过重新设计,简化了设置流程,更新了项目结构,并改进了默认值。新模板默认包含 App Router、TypeScript 优先配置、Tailwind CSS 和 ESLint。
构建适配器 API (alpha)
在构建适配器 RFC之后,我们与社区和部署平台合作,发布了 Build Adapters API 的第一个 Alpha 版本。
构建适配器允许您创建自定义适配器,这些适配器可以连接到构建过程,使部署平台和自定义构建集成能够修改 Next.js 配置或处理构建输出。
const nextConfig = {
experimental: {
adapterPath: require.resolve('./my-adapter.js'),
},
};
module.exports = nextConfig;在 RFC 讨论中分享您的反馈。
React 编译器支持(稳定版)
在 React Compiler 1.0 发布后,Next.js 16 中对 React Compiler 的内置支持现已稳定。React Compiler 自动记忆组件,无需手动代码更改即可减少不必要的重新渲染。
reactCompiler 配置选项已从 experimental 升级到稳定版。它默认未启用,因为我们仍在收集不同应用程序类型的构建性能数据。启用此选项时,由于 React Compiler 依赖于 Babel,因此开发和构建期间的编译时间预计会更高。
const nextConfig = {
reactCompiler: true,
};
export default nextConfig;安装最新版本的 React Compiler 插件
npm install babel-plugin-react-compiler@latest核心功能和架构
增强的路由和导航
Next.js 16 包含了对路由和导航系统的全面改进,使页面转换更精简、更快速。
布局去重:当预取多个共享布局的 URL 时,布局只会下载一次,而不是每个链接单独下载。例如,一个包含 50 个产品链接的页面现在只会下载一次共享布局,而不是 50 次,从而显著减少了网络传输大小。
增量预取:Next.js 只预取尚未缓存的部分,而不是整个页面。预取缓存现在:
- 当链接离开视口时取消请求
- 在悬停或重新进入视口时优先预取链接
- 当数据失效时重新预取链接
- 与即将推出的缓存组件等功能无缝协作
权衡:您可能会看到更多的单个预取请求,但总传输大小会大大降低。我们相信这对于几乎所有应用程序来说都是正确的权衡。如果增加的请求数量导致问题,请告诉我们。我们正在研究额外的优化方案,以更高效地内联数据块。
这些更改无需修改代码,旨在提高所有应用程序的性能。
改进的缓存 API
Next.js 16 引入了经过优化的缓存 API,可更明确地控制缓存行为。
revalidateTag()(已更新)
revalidateTag() 现在需要一个 cacheLife 配置文件 作为第二个参数,以启用陈旧时重新验证 (SWR) 行为。
import { revalidateTag } from 'next/cache';
// ✅ Use built-in cacheLife profile (we recommend 'max' for most cases)
revalidateTag('blog-posts', 'max');
// Or use other built-in profiles
revalidateTag('news-feed', 'hours');
revalidateTag('analytics', 'days');
// Or use an inline object with a custom revalidation time
revalidateTag('products', { revalidate: 3600 });
// ⚠️ Deprecated - single argument form
revalidateTag('blog-posts');配置文件参数接受内置的 cacheLife 配置文件名称(例如 'max'、'hours'、'days')或在 next.config 中定义的自定义配置文件。您也可以传入一个内联的 { expire: number } 对象。我们建议在大多数情况下使用 'max',因为它为长期存在的内容启用了后台重新验证。当用户请求带标签的内容时,他们会立即收到缓存数据,而 Next.js 会在后台重新验证。
当您希望仅通过陈旧时重新验证行为使正确标记的缓存条目失效时,请使用 revalidateTag()。这非常适合可以容忍最终一致性的静态内容。
迁移指南:为 SWR 行为添加带有
cacheLife配置文件的第二个参数(我们建议使用'max'),或者如果您需要读写一致性语义,请在服务器操作中使用updateTag()。
updateTag()(新)
updateTag() 是一个新的仅限服务器操作的 API,提供读写一致性语义,在同一请求中过期并立即读取新鲜数据。
'use server';
import { updateTag } from 'next/cache';
export async function updateUserProfile(userId: string, profile: Profile) {
await db.users.update(userId, profile);
// Expire cache and refresh immediately - user sees their changes right away
updateTag(`user-${userId}`);
}这确保了交互式功能能够立即反映更改。非常适合表单、用户设置以及任何用户期望立即看到其更新的工作流程。
refresh()(新)
refresh() 是一个新的仅限服务器操作的 API,用于刷新仅未缓存的数据。它根本不触及缓存。
'use server';
import { refresh } from 'next/cache';
export async function markNotificationAsRead(notificationId: string) {
// Update the notification in the database
await db.notifications.markAsRead(notificationId);
// Refresh the notification count displayed in the header
// (which is fetched separately and not cached)
refresh();
}此 API 是客户端 router.refresh() 的补充。当您在执行操作后需要刷新页面上其他地方显示的未缓存数据时使用它。您的缓存页面外壳和静态内容保持快速,而动态数据(如通知计数、实时指标或状态指示器)会刷新。
React 19.2 和 Canary 功能
Next.js 16 中的 App Router 使用最新的 React Canary 版本,其中包括新发布的 React 19.2 功能和其他正在逐步稳定的功能。亮点包括:
- 视图过渡:动画在过渡或导航内部更新的元素
useEffectEvent:将 Effects 中的非反应式逻辑提取到可重用的 Effect Event 函数中- 活动:通过使用
display: none隐藏 UI 同时保持状态并清理 Effects 来渲染“后台活动”
在 React 19.2 公告中了解更多信息。
重大更改和其他更新
版本要求
| 更改 | 详情 |
|---|---|
| Node.js 20.9+ | 最低版本现为 20.9.0 (LTS);不再支持 Node.js 18 |
| TypeScript 5+ | 最低版本现为 5.1.0 |
| 浏览器 | Chrome 111+、Edge 111+、Firefox 111+、Safari 16.4+ |
移除
这些功能以前已被弃用,现在已移除
| 已移除 | 替换 |
|---|---|
| AMP 支持 | 所有 AMP API 和配置已删除(useAmp、export const config = { amp: true }) |
next lint 命令 | 直接使用 Biome 或 ESLint;next build 不再运行 linting。提供了 codemod:npx @next/codemod@canary next-lint-to-eslint-cli . |
devIndicators 选项 | appIsrStatus、buildActivity、buildActivityPosition 已从配置中删除。指示器仍然存在。 |
serverRuntimeConfig、publicRuntimeConfig | 使用环境变量(.env 文件) |
experimental.turbopack 位置 | 配置已移至顶级 turbopack(不再位于 experimental 中) |
experimental.dynamicIO 标志 | 重命名为 cacheComponents |
experimental.ppr 标志 | PPR 标志已删除;演变为缓存组件编程模型 |
export const experimental_ppr | 路由级别 PPR 导出已删除;演变为缓存组件编程模型 |
自动 scroll-behavior: smooth | 在 HTML 文档中添加 data-scroll-behavior="smooth" 以重新选择 |
unstable_rootParams() | 我们正在开发一个替代 API,并将在即将发布的次要版本中提供 |
同步 params、searchParams 属性访问 | 必须使用异步:await params, await searchParams |
同步 cookies()、headers()、draftMode() 访问 | 必须使用异步:await cookies()、await headers()、await draftMode() |
元数据图像路由 params 参数 | 更改为异步 params;generateImageMetadata 中的 id 现在是 Promise<string> |
带有查询字符串的 next/image 本地 src | 现在需要 images.localPatterns 配置以防止枚举攻击 |
行为变更
这些功能在 Next.js 16 中具有新的默认行为
| 更改的行为 | 详情 |
|---|---|
| 默认打包器 | Turbopack 现在是所有应用程序的默认打包器;通过 next build --webpack 选择退出 |
images.minimumCacheTTL 默认值 | 从 60 秒更改为 4 小时 (14400 秒);降低了没有缓存控制头部的图像的重新验证成本 |
images.imageSizes 默认值 | 从默认尺寸中删除 16(仅 4.2% 的项目使用);减少了 srcset 大小和 API 变体 |
images.qualities 默认值 | 从 [1..100] 更改为 [75];quality 属性现在被强制转换为 images.qualities 中最接近的值 |
images.dangerouslyAllowLocalIP | 新的安全限制默认阻止本地 IP 优化;仅对私有网络设置为 true |
images.maximumRedirects 默认值 | 从无限制更改为最多 3 次重定向;设置为 0 禁用或增加以应对罕见边缘情况 |
@next/eslint-plugin-next 默认值 | 现在默认采用 ESLint Flat Config 格式,与将放弃旧版配置支持的 ESLint v10 对齐 |
| 预取缓存行为 | 通过布局去重和增量预取进行了完全重写 |
revalidateTag() 签名 | 现在需要 cacheLife 配置文件作为第二个参数以实现陈旧时重新验证行为 |
| Turbopack 中的 Babel 配置 | 如果找到 Babel 配置,则自动启用 Babel(以前会以硬错误退出) |
| 终端输出 | 重新设计,具有更清晰的格式、更好的错误消息和改进的性能指标 |
| 开发和构建输出目录 | next dev 和 next build 现在使用单独的输出目录,从而实现并发执行 |
| 锁文件行为 | 添加了锁文件机制,以防止在同一项目上运行多个 next dev 或 next build 实例 |
并行路由 default.js | 所有并行路由槽位现在都需要显式的 default.js 文件;没有它们将导致构建失败。创建调用 notFound() 或返回 null 的 default.js 以获得之前的行为 |
| 现代 Sass API | 将 sass-loader 升级到 v16,支持现代 Sass 语法和新功能 |
弃用
这些功能在 Next.js 16 中已弃用,并将在未来版本中移除
| 已弃用 | 详情 |
|---|---|
middleware.ts 文件名 | 重命名为 proxy.ts 以明确网络边界和路由重点 |
next/legacy/image 组件 | 改用 next/image 以获得改进的性能和功能 |
images.domains 配置 | 改用 images.remotePatterns 配置以提高安全限制 |
revalidateTag() 单参数 | 对于 SWR,使用 revalidateTag(tag, profile);对于读写一致性,在 Actions 中使用 updateTag(tag) |
额外改进
- 性能改进:
next dev和next start命令的显著性能优化 - Node.js
next.config.ts的原生 TypeScript:运行next dev、next build和next start命令时带上--experimental-next-config-strip-types标志,以启用next.config.ts的原生 TypeScript 支持。
我们将在文档中发布稳定版本之前,提供更全面的迁移指南。
反馈与社区
分享您的反馈,帮助塑造 Next.js 的未来
贡献者
Next.js 是超过 3,000 名独立开发者共同努力的成果。此版本由以下团队提供
- Next.js 团队:Andrew、Hendrik、Janka、Jiachi、Jimmy、Jiwon、JJ、Josh、Jude、Sam、Sebastian、Sebbie、Wyatt 和 Zack。
- Turbopack 团队:Benjamin、Josh、Luke、Niklas、Tim、Tobias 和 Will。
- Next.js 文档 团队:Delba、Rich、Ismael 和 Joseph。
衷心感谢 @mischnic、@timneutkens、@unstubbable、@wyattjoh、@Cy-Tek、@lukesandberg、@OoMNoO、@ztanner、@icyJoseph、@huozhi、@gnoff、@ijjk、@povilasv、@dwrth、@obendev、@aymericzip、@devjiwonchoi、@SyMind、@vercel-release-bot、@Shireee、@eps1lon、@dharun36、@kachkaev、@bgw、@yousefdawood7、@TheAlexLichter、@sokra、@ericx0099、@leerob、@Copilot、@fireairforce、@fufuShih、@anvibanga、@hayes、@Milancen123、@martinfrancois、@lubieowoce、@gaojude、@lachlanjc、@liketiger、@styfle、@aaronbrown-vercel、@Samii2383、@FelipeChicaiza、@kevva、@m1abdullahh、@F7b5、@Anshuman71、@RobertFent、@poteto、@chloe-yan、@sireesha-siri、@brian-lou、@joao4xz、@stefanprobst、@samselikoff、@acdlite、@gwkline、@bgub、@brock-statsig 和 @karlhorky 的帮助!