跳到内容
返回博客

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,这是一个快速的 CSS 打包器和压缩器,用 Rust 编写。

我们一直在 Vercel 的应用程序中广泛地使用 Turbopack。例如,对于 vercel.com 这个大型 Next.js 应用程序,我们看到了

  • 本地服务器启动速度提升高达 76.7%
  • 使用快速刷新进行代码更新的速度提升高达 96.3%
  • 在没有缓存的情况下(Turbopack 尚不具备磁盘缓存),初始路由编译速度提升高达 45.8%

Turbopack 仍然是可选的,您可以使用以下命令试用:

终端
next dev --turbo

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

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

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

构建和生产改进

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

Tree-shaking

我们发现了服务器组件和客户端组件之间边界的优化,可以 tree-shaking 未使用的导出。例如,从具有 "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 Modules 而不是 全局样式
  • 仅在单个 JS/TS 文件中导入 CSS Module。
  • 如果使用全局类名,也在同一个 JS/TS 中导入全局样式。

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

缓存改进

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

staleTimes(实验性)

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

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

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

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

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

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

并行路由和拦截路由

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

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

错误 DX 改进

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

例如,React Hydration 错误是我们社区中常见的困惑来源。虽然我们进行了改进以帮助用户查明 hydration 不匹配的来源(见下文),但我们正在与 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

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

诸如 Actions 及其相关 hooks 等新功能,这些功能已在 Next.js 中通过 React canary channel 提供,现在将可用于所有 React 应用程序(包括仅客户端应用程序)。我们很高兴看到这些功能在 React 生态系统中得到更广泛的应用。

其他改进

  • [文档] 关于视频优化的新文档 (PR)。
  • [文档] 关于 instrumentation.ts 的新文档 (PR)
  • [功能] next/image 的新 overrideSrc 属性 (PR)。
  • [功能] getStaticProps 的新 revalidateReason 参数 (PR)。
  • [改进] 重构了流式传输逻辑,减少了在生产环境中流式传输页面的时间 (PR)。
  • [改进] 支持嵌套服务器操作 (PR)。
  • [改进] 支持在生成的站点地图中进行本地化 (PR)。
  • [改进] 开发和构建日志的视觉改进 (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 DiscussionsRedditDiscord 上的对话。

贡献者

Next.js 是超过 3,000 名个人开发者、谷歌和 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 的帮助!