跳到内容
返回博客

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。例如,对于 vercel.com,一个大型 Next.js 应用程序,我们已经看到

  • 本地服务器启动速度提升高达 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 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 (CSS 模块) 而不是 全局样式
  • 仅在单个 JS/TS 文件中导入 CSS Module。
  • 如果使用全局类名,也在同一个 JS/TS 文件中导入全局样式。

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

缓存改进

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

staleTimes (实验性)

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

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

默认情况下,预取的路由(使用不带 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 的信息。

并行路由和拦截路由

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

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

错误 DX 改进

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

例如,React Hydration (React 水合) 错误是我们社区中常见的困惑来源。虽然我们已经进行了改进以帮助用户查明 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 (钩子) 等新功能,这些功能已在 React canary channel (React 金丝雀通道) 中在 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 Actions (服务器行为) 在从引用页面导航离开后触发,或在非活动并行路由段内使用时,找不到操作清单中的 Server Actions (服务器行为) 的错误 (PR)
  • [改进] 修复了 next/dynamic 加载的组件中的 CSS 导入 (PR)。
  • [改进] 当动画图像缺少 unoptimized 属性时发出警告 (PR)。
  • [改进] 如果 images.loaderFile 未导出默认函数,则显示错误消息 (PR)

社区

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

贡献者

Next.js 是超过 3,000 名个人开发者、行业合作伙伴(如 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 的帮助!