跳至内容
返回博客

2024年4月11日,星期四

Next.js 14.2

发布者

Next.js 14.2 包含开发、生产和缓存改进。

立即升级或使用以下方法开始

终端
npx create-next-app@latest

开发版 Turbopack(发布候选版本)

在过去的几个月里,我们一直在努力使用 Turbopack 提高本地开发性能。在 14.2 版本中,Turbopack 的**发布候选版本**现已可用于本地开发。

  • 99.8%集成测试 现已通过。
  • 我们已验证 Next.js 应用程序中使用的排名前 300 的 npm 包可以使用 Turbopack 编译。
  • 所有 Next.js 示例 均可与 Turbopack 配合使用。
  • 我们集成了 Lightning CSS,这是一个用 Rust 编写的快速 CSS 捆绑器和缩小器。

我们已使用 Vercel 的应用程序广泛试用 Turbopack。例如,对于大型 Next.js 应用程序 vercel.com,我们看到了

  • 本地服务器启动速度提高了76.7%
  • 使用快速刷新更新代码的速度提高了96.3%
  • 初始路由编译(无缓存)速度提高了45.8%(Turbopack 尚未具有磁盘缓存)。

Turbopack 仍处于选择加入状态,您可以使用以下方法试用

终端
next dev --turbo

我们现在将专注于改进内存使用情况、实现持久缓存以及 next build --turbo

  • 内存使用情况 - 我们构建了用于调查内存使用情况的底层工具。您现在可以 生成跟踪文件,其中包含性能指标和广泛的内存使用情况信息。这些跟踪文件使我们能够在无需访问您的应用程序源代码的情况下调查性能和内存使用情况。
  • 持久缓存 - 我们还在探索最佳的架构选项,并预计将在未来版本中分享更多详细信息。
  • next build - 虽然 Turbopack 尚未可用于构建,但74.7% 的测试已通过。您可以在 areweturboyet.com/build 跟踪进度。

要查看 Turbopack 中支持的不支持的功能列表,请参阅我们的 文档

构建和生产改进

除了使用 Turbopack 捆绑改进外,我们还努力提高所有 Next.js 应用程序(页面和 App 路由器)的整体构建和生产性能。

Tree-shaking

我们确定了服务器组件和客户端组件之间边界的优化,允许对未使用的导出进行 tree-shaking。例如,从包含 "use client" 的文件中导入单个 Icon 组件不再包含该包中的所有其他图标。这可以大大减少生产 JavaScript 捆绑包的大小。

在流行库(如 react-aria-components)上测试此优化可将最终捆绑包大小减少-51.3%

注意:此优化目前不适用于桶文件。同时,您可以使用 optimizePackageImports 配置选项

next.config.ts
module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
};

构建内存使用情况

对于极其大规模的 Next.js 应用程序,我们在生产构建期间注意到内存不足崩溃(OOM)。在调查用户报告和重现后,我们发现根本原因是过度捆绑和缩小(Next.js 创建了更少、更大的 JavaScript 文件,并存在重复)。我们已经重构了捆绑逻辑并针对这些情况优化了编译器。

我们的早期测试表明,在最小的 Next.js 应用程序上,内存使用量和缓存文件大小平均从2.2GB 减少到 190MB 以下

为了更轻松地调试内存性能,我们在 next build 中引入了 --experimental-debug-memory-usage 标志。在我们的 文档 中了解更多信息。

CSS

我们更新了生产 Next.js 构建期间 CSS 的优化方式,通过对 CSS 进行分块来避免在页面之间导航时出现冲突的样式。

CSS 块的顺序和合并现在由导入顺序定义。例如,base-button.module.css 将在 page.module.css 之前排序。

base-button.tsx
import styles from './base-button.module.css';
 
export function BaseButton() {
  return <button className={styles.primary} />;
}
page.tsx
import { BaseButton } from './base-button';
import styles from './page.module.css';
 
export function Page() {
  return <BaseButton className={styles.primary} />;
}

为了保持正确的 CSS 顺序,我们建议

  • 使用 CSS 模块 而不是 全局样式
  • 仅在一个 JS/TS 文件中导入 CSS 模块。
  • 如果使用全局类名,则也在同一个 JS/TS 中导入全局样式。

我们预计此更改不会对大多数应用程序产生负面影响。但是,如果您在升级时看到任何意外样式,请根据我们 文档 中的建议查看 CSS 导入顺序。

缓存改进

缓存是构建快速可靠的 Web 应用程序的关键部分。在执行变异时,用户和开发人员都希望缓存更新以反映最新的更改。我们一直在探索如何在 App 路由器中改进 Next.js 缓存体验。

staleTimes (实验性功能)

客户端路由缓存 (Client-side Router Cache) 是一种缓存层,旨在通过缓存客户端上访问过的和预取的路由来提供快速的导航体验。

根据社区反馈,我们添加了一个实验性的 staleTimes 选项,允许配置客户端路由缓存的失效时间。

默认情况下,预取的路由(使用 <Link> 组件且未设置 prefetch 属性)将缓存 30 秒,如果 prefetch 属性设置为 true,则缓存 5 分钟。您可以通过在 next.config.js 中定义自定义的重新验证时间 (revalidation times) 来覆盖这些默认值。

next.config.ts
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
      static: 180,
    },
  },
};
 
module.exports = nextConfig;

staleTimes 的目标是改善希望更多控制缓存启发式的用户的当前体验,但它并非旨在成为完整的解决方案。在即将发布的版本中,我们将专注于改进整体缓存语义并提供更灵活的解决方案。

在我们的 文档 中了解更多关于 staleTimes 的信息。

并行路由和拦截路由

我们正在继续迭代 并行路由拦截路由,现在正在改进与客户端路由缓存的集成。

  • 使用 revalidatePathrevalidateTag 调用服务器操作的并行路由和拦截路由将重新验证缓存并刷新可见的插槽,同时保持用户的当前视图。
  • 类似地,调用 router.refresh 现在可以正确地刷新可见的插槽,同时保持当前视图。

错误 DX 改进

在 14.1 版本中,我们开始着手改进运行 next dev 时错误消息和堆栈跟踪的可读性 (improved the readability of error messages and stack traces)。这项工作一直持续到 14.2 版本,现在包括更好的错误消息、App Router 和 Pages Router 的覆盖层设计改进、亮色和暗色模式支持,以及更清晰的 devbuild 日志。

例如,React 水合错误是我们社区中常见的困惑来源。虽然我们进行了改进以帮助用户查明水合不匹配的来源(见下文),但我们正在与 React 团队合作改进底层错误消息,并显示发生错误的文件名。

之前

An example of the Next.js error overlay before version 14.2.
14.2 版本之前的 Next.js 错误覆盖层示例。

之后

An example of the Next.js error overlay after version 14.2.
14.2 版本之后的 Next.js 错误覆盖层示例。

React 19

2 月份,React 团队宣布了即将发布的 React 19。为了准备 React 19,我们正在努力将最新的功能和改进集成到 Next.js 中,并计划发布一个主要版本来协调这些更改。

像 Actions 及其相关 Hook 这样的新功能,从 React canary 频道 开始就在 Next.js 中可用,现在将对所有 React 应用程序(包括仅客户端的应用程序)都可用。我们很高兴看到这些功能在 React 生态系统中得到更广泛的采用。

其他改进

  • [文档] 关于视频优化的新增文档 (PR).
  • [文档] 关于 instrumentation.ts 的新增文档 (PR)
  • [功能] next/image 的新增 overrideSrc 属性 (PR).
  • [功能] getStaticProps 的新增 revalidateReason 参数 (PR).
  • [改进] 重构了流式传输逻辑,减少了在生产环境中流式传输页面的时间 (PR).
  • [改进] 支持嵌套服务器操作 (PR).
  • [改进] 支持在生成的站点地图中进行本地化 (PR).
  • [改进] dev 和 build 日志的视觉改进 (PR)
  • [改进] 倾斜保护在 Vercel 上稳定 (文档).
  • [改进] 使 useSelectedLayoutSegment 与 Pages Router 兼容 (PR).
  • [改进] 当绝对 URL 不需要解析时跳过 metadataBase 警告 (PR).
  • [改进] 修复部署到 Vercel 时,服务器操作在未启用 JavaScript 时无法提交的问题 (PR)
  • [改进] 修复如果在导航离开引用页面后触发,或在非活动并行路由段内使用,则找不到操作清单中的服务器操作的错误 (PR)
  • [改进] 修复由 next/dynamic 加载的组件中的 CSS 导入问题 (PR).
  • [改进] 当动画图像缺少 unoptimized 属性时发出警告 (PR).
  • [改进] 如果images.loaderFile未导出默认函数,则显示错误消息(PR)

社区

Next.js 现在每月拥有超过 100 万活跃开发者。我们感谢社区的支持和贡献。加入关于 GitHub 讨论RedditDiscord 的对话。

贡献者

Next.js 是超过 3000 位独立开发者、谷歌和 Meta 等行业合作伙伴以及我们在 Vercel 的核心团队共同努力的结果。此版本由以下人员提供支持

非常感谢 @taishikato、@JesseKoldewijn、@Evavic44、@feugy、@liamlaverty、@dvoytenko、@SukkaW、@wbinnssmith、@rishabhpoddar、@better-salmon、@ziyafenn、@A7med3bdulBaset、@jasonuc、@yossydev、@Prachi-meon、@InfiniteCodeMonkeys、@ForsakenHarmony、@miketimmerman、@kwonoj、@williamli、@gnoff、@jsteele-stripe、@chungweileong94、@WITS、@sogoagain、@junioryono、@eisafaqiri、@yannbolliger、@aramikuto、@rocketman-21、@kenji-webdev、@michaelpeterswa、@Dannymx、@vpaflah、@zeevo、@chrisweb、@stefangeneralao、@tknickman、@Kikobeats、@ubinatus、@code-haseeb、@hmmChase、@byhow、@DanielRivers、@wojtekmaj、@paramoshkinandrew、@OMikkel、@theitaliandev、@oliviertassinari、@Ishaan2053、@Sandeep-Mani、@alyahmedaly、@Lezzio、@devjiwonchoi、@juliusmarminge、@szmazhr、@eddiejaoude、@itz-Me-Pj、@AndersDJohnson、@gentamura、@tills13、@dijonmusters、@SaiGanesh21、@vordgi、@ryota-murakami、@tszhong0411、@officialrajdeepsingh、@alexpuertasr、@AkifumiSato、@Jonas-PFX、@icyJoseph、@florian-lp、@pbzona、@erfanium、@remcohaszing、@bernardobelchior、@willashe、@kevinmitch14、@smakosh、@mnjongerius、@asobirov、@theoholl、@suu3、@ArianHamdi、@adrianha、@Sina-Abf、@kuzeykose、@meenie、@nphmuller、@javivelasco、@belgattitude、@Svetoslav99、@johnslemmer、@colbyfayock、@mehranmf31、@m-nakamura145、@ryo8000、@aryaemami59、@bestlyg、@jinsoul75、@petrovmiroslav、@nattui、@zhuyedev、@dongwonnn、@nhducit、@flotwig、@Schmavery、@abhinaypandey02、@rvetere、@coffeecupjapan、@cjimmy、@Soheiljafarnejad、@jantimon、@zengspr、@wesbos、@neomad1337、@MaxLeiter 和 @devr77 的帮助!