跳到内容
返回博客

2024年4月11日星期四

Next.js 14.2

发布者

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

立即升级或开始使用

终端
npx create-next-app@latest

Turbopack for Development (发布候选版)

在过去的几个月里,我们一直致力于通过 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%
  • 使用 Fast Refresh 进行代码更新的速度提升高达 96.3%
  • 在没有缓存的情况下,初始路由编译速度提升高达 45.8%(Turbopack 尚无磁盘缓存)。

Turbopack 仍然是可选的,您可以通过以下方式试用:

终端
next dev --turbo

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

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

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

构建和生产改进

除了使用 Turbopack 改进捆绑之外,我们还致力于提高所有 Next.js 应用程序(包括 Pages 和 App Router)的整体构建和生产性能。

摇树优化

我们为 Server 和 Client 组件之间的边界确定了一个优化,允许对未使用的导出进行摇树优化。例如,从包含 "use client" 的文件中导入单个 Icon 组件不再包含该包中的所有其他图标。这可以在很大程度上减小生产 JavaScript 包的大小。

react-aria-components 这样的流行库上测试此优化后,最终包大小减少了 -51.3%

注意:此优化目前不适用于 barrel 文件。同时,您可以使用 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 Router 中的 Next.js 缓存体验。

staleTimes (实验性)

客户端路由缓存是一个旨在通过在客户端缓存已访问和预取的路由来提供快速导航体验的缓存层。

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

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

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

staleTimes 旨在改善当前用户对缓存启发式算法有更多控制的需求,但它并非完整的解决方案。在即将发布的版本中,我们将专注于改进整体缓存语义并提供更灵活的解决方案。

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

并行路由和拦截路由

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

  • 调用带有 revalidatePathrevalidateTag 的 Server Actions 的并行路由和拦截路由将重新验证缓存并刷新可见插槽,同时保持用户当前视图。
  • 同样,调用 router.refresh 现在可以正确刷新可见插槽,保持当前视图。

错误开发体验改进

在 14.1 版本中,我们开始致力于 改进运行 next dev 时的错误消息和堆栈跟踪的可读性。这项工作已延续到 14.2 版本,现在包括更好的错误消息、App Router 和 Pages Router 的叠加层设计改进、亮色和暗色模式支持以及更清晰的 devbuild 日志。

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

之前

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

之后

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

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)。
  • [改进] 支持嵌套 Server Actions (PR)。
  • [改进] 支持生成站点地图中的本地化 (PR)。
  • [改进] 开发和构建日志的视觉改进 (PR)
  • [改进] Vercel 上的倾斜保护稳定 (文档)。
  • [改进] 使 useSelectedLayoutSegment 与 Pages Router 兼容 (PR)。
  • [改进] 当不需要解析绝对 URL 时,跳过 metadataBase 警告 (PR)。
  • [改进] 修复在部署到 Vercel 时,如果未启用 JavaScript,Server Actions 未提交的问题 (PR)
  • [改进] 修复了当 Server Action 在从引用页面导航离开后触发,或者在非活动的并行路由段中使用时,找不到 actions manifest 中 Server Action 的错误 (PR)
  • [改进] 修复了 next/dynamic 加载的组件中的 CSS 导入问题 (PR)。
  • [改进] 当动画图像缺少 unoptimized 属性时发出警告 (PR)。
  • [改进] 如果 images.loaderFile 没有导出默认函数,则显示错误消息 (PR)

社区

Next.js 现已拥有超过 100 万月活跃开发者。我们感谢社区的支持和贡献。请加入我们的讨论:GitHub DiscussionsRedditDiscord

贡献者

Next.js 是由 3000 多名独立开发者、Google 和 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 的帮助!