2024年10月21日,星期一
Turbopack Dev 现已稳定
发布者历经漫长的道路,我们很高兴地宣布 next dev --turbo
现已稳定,并准备好加速您的开发体验。我们一直在使用它来迭代 vercel.com、 nextjs.org、 v0 以及我们所有其他应用程序,并取得了非常好的效果。
自 8 年前发布以来,Next.js 已被用于构建各种项目,从周末的业余爱好项目到复杂的企业应用程序。在 Next.js 首次发布时,webpack 显然是框架捆绑基础的最佳选择,但随着时间的推移,它已难以跟上现代 Web 开发人员的需求。我们的社区开始发现,在等待路由加载、代码更改反映以及生产版本部署时,迭代速度慢得令人痛苦。
我们投入了大量时间和精力来优化 webpack,但在某个时候,我们觉得投入的精力没有获得足够的改进。我们需要一个新的基础,它既能支持当今已投入生产的众多 Next.js 应用程序,又能支持我们计划的未来创新,例如 React Server Components。
这些是我们对新捆绑器的要求
- 最小的破坏性更改
- 同时支持 App Router 和 Pages Router
- 所有规模代码库更快的编译速度
- 与生产环境高度一致的开发构建
- 高级的生产环境优化(例如,模块内的 tree shaking)
- 支持 Node.js 和浏览器等多种环境的模块图
- 维护者和高级用户的完全可观察性
我们评估了当时所有现有的解决方案,发现每种方案都有权衡,未能与我们的要求和目标相符。因此,从头开始设计一些东西来精确地满足 Next.js 今天的需求,并掌握路线图,以便我们可以构建和试验它明天需要的东西,这对于我们来说是有意义的。这就是我们创建 Turbopack 的动机。
我们首先优化了开发体验,这就是我们今天发布的稳定版本。我们一直在 Vercel 的应用程序上广泛地使用 Turbopack 进行内部测试,并且我们开发人员的迭代速度得到了显著提高。例如,对于大型 Next.js 应用程序 vercel.com,我们已经看到:
- 本地服务器启动速度提升高达 **76.7%**。
- 使用 Fast Refresh 进行代码更新的速度提升高达 **96.3%**。
- 首次路由编译速度提升高达 **45.8%**,且不使用缓存(Turbopack 尚无磁盘缓存)。
在本文中,我们将讨论我们如何实现这些结果,以及其他一些亮点。我们还将明确说明对此版本的期望,并提供有关后续内容的路线图。
亮点
更快的路由初始编译速度
我们从社区听到的最大的问题之一是,路由在开发环境中加载时间过长,这归根结底是 webpack 的编译速度问题。Next.js 按需编译路由,以避免在需要之前编译所有可能的路由,这保持了初始启动速度快和内存使用率低,但即便如此,您仍然可能会发现自己在等待单个页面加载时不停地敲脚。
公平地说,像 webpack 这样的捆绑器在底层做了很多工作。首次编译路由时,捆绑器从“入口点”开始。在 Next.js 的情况下,它是 page.tsx
以及该路由的所有相关文件(如 layout.tsx
和 loading.tsx
等)的组合。解析这些入口点以查找 import
语句,这些语句被解析为文件,然后像入口点一样处理这些文件,并且此循环持续进行,直到找不到更多导入。此过程构建了一个模块图,该模块图不仅可以由 TypeScript / JavaScript 模块(包括 node_modules
)组成,还可以由 CSS 文件(全局 CSS 和 CSS 模块)和静态文件(如用于 next/image
的导入图像)组成。
在收集所有模块后,模块图用于创建 JavaScript 包,通常称为“chunks”。这些 chunks 是编译器在服务器(构建时或运行时)或浏览器上运行的输出。
webpack 不支持创建为多种环境生成输出的图,因此我们今天必须在 Next.js 中使用 webpack 运行至少两个单独的编译器,一个用于服务器,一个用于浏览器。我们必须首先编译服务器模块图,以便可以找到所有对 "use client"
的引用。构建服务器后,我们遍历其图以创建浏览器编译器的相关入口点。由于这是一个单独的 webpack 编译器,因此此过程中存在一些开销,例如在客户端和服务器之间解析相同的代码两次。
使用 Turbopack,我们着手消除运行多个编译器并在它们之间进行协调的开销。解决方案是使编译器能够识别多个不同的输出目标。在内部,这些称为目标“转换”。我们可以将导入标记为从服务器到浏览器或从浏览器到服务器的转换。这使得 Turbopack 能够高效地捆绑 Server Components 和 Client Components,以及从 Client Components 导入的 Server Functions。
除了提高性能外,拥有一个可以在单次传递中处理多种环境的编译器还具有可靠性和调试优势,因为我们不再需要在 Next.js 中在两个单独的编译器进程之间进行协调。
webpack 和 Turbopack 之间的另一个重大区别是 Turbopack 可以跨多个 CPU 并行化工作,而 webpack 仅并行化使用 SWC 的 TypeScript / JavaScript 转换步骤。
webpack 不支持跨 CPU 并行化,因为为了有效地并行化,数据必须易于跨线程访问。webpack 的构建方式大量使用了大型 JavaScript 对象,这些对象无法在线程之间轻松共享,而无需昂贵的序列化和反序列化。这种开销通常会抵消利用多个 CPU 带来的性能提升。Turbopack 用 Rust 编写,没有相同的限制,并且从一开始就考虑了并行化。
我们还通过更快的 filesystem 读写、更快的模块解析以及跳过更多关于无副作用模块的工作,实现了性能提升。
在大型 Next.js 应用程序 vercel.com
上使用 Turbopack 时,与使用 webpack 的 Next.js 相比,我们已经看到初始编译速度提升高达 **45.8%**。
更快的 Fast Refresh
Fast Refresh 是捆绑器用来将更改传播到您当前在浏览器中查看的路由的系统,有时称为热模块替换 (HMR)。
Next.js 具有更深入的集成,将 Fast Refresh 连接到 React,确保在您更改组件时 React 不会丢失状态。
使用 webpack,我们发现当您达到一定数量的 JavaScript 模块时,Fast Refresh 的性能会受到限制。Webpack 需要进行图遍历并为即使未更改的模块生成输出,并与 JavaScript 模块的数量线性扩展。
我们发现,在大约 30,000 个模块时,代码更改始终至少有 1 秒的开销来处理更新,无论更改是否很小。例如,更改 CSS 文件中的颜色可能需要 1 秒才能在屏幕上显示。
这种性能对我们来说是不可接受的。我们认为,增量构建应该仅根据本地更改的大小进行扩展,而不是根据路由或应用程序的大小进行扩展。当 button.tsx
更改时,编译器应该只运行与该文件更改相关的工作,而不是重新计算不受更改影响的其他模块和输出文件。为了解决这个问题,我们在 Turbopack 中优先考虑了一个允许非常精细地重新计算工作的基础。
这项努力转化为底层库 Turbo Engine,它使用自动按需驱动的增量计算架构,以在数十毫秒内为大型 Next.js 和 React 应用程序提供交互式热重载。此架构基于十多年的研究和现有技术,包括 webpack、 Salsa、 Parcel、 Adapton 和 Rust 编译器的查询系统。
现在使用 Turbopack,Fast Refresh 速度会根据您的更改大小进行扩展,这就是我们如何在大型 Next.js 应用程序(如 vercel.com)上使用 Fast Refresh 实现 **96.3% 更快** 的代码更新的原因。
高级追踪
随着 Next.js 多年来的采用率不断提高,我们发现越来越难以重现 GitHub 上报告的问题,尤其是与编译器性能和内存使用情况相关的问题。这是因为大多数人无法共享他们的应用程序代码,或者当他们共享代码时,应用程序无法运行,因为它需要数据库或其他设置。
为了开始解决这个问题,我们在 Next.js 的内部结构中添加了追踪。这些追踪信息被写入 .next
文件夹中的一个文件,并且不包含应用程序代码 —— 仅包含文件路径、编译器花费的时间以及其他时间信息,例如单个转换。但是,使用 webpack,我们从来没有一种好的方法来清楚地区分编译器的内存使用情况与框架或应用程序代码的内存使用情况,因为它们都在同一个 Node.js 实例中运行。
使用 Turbopack,我们能够从一开始就进行仪器化设计。我们在 Turbo Engine 中实现了一个仪器化层,允许收集每个单独函数的计时信息。我们能够扩展这些追踪信息,以跟踪每个函数的内存分配、释放和持久内存。
这种新的高级追踪为我们提供了深入调查减速和内存使用情况所需的所有信息;它只需要追踪信息,而不是完整的代码库。
为了处理这些新的追踪信息,我们实现了一个自定义的追踪查看器,无论应用程序和追踪信息的大小如何,它都能保持高性能。它是一个专门为调查 Turbopack 的减速和内存使用情况而构建的追踪查看器,并且由于它缩短了反馈循环,因此使我们能够在许多早期采用者应用程序中优化性能。
虽然追踪查看器最初是为内部使用而构建的(并且它旨在用于需要深入技术分析的情况),但我们已经实现了在 Next.js 中自行运行它所需的组件。您可以使用这些说明生成 Turbopack 追踪信息。然后,当生成追踪信息后,您可以使用 next internal turbo-trace-server .next/trace-turbopack
启动服务器,以便检查追踪信息。此处提供了一个追踪查看器的快速视频概述:点击此处。
编译时间的波动性更小
当将 Next.js 与 webpack 一起使用时,编译时间通常不够透明。在一种情况下,打开一个页面可能需要 10 秒,而在另一种情况下,可能需要 20 秒。虽然可能存在缓存,但有时它没有足够的效力来产生一致的结果。即使在没有缓存的情况下进行编译,我们也看到了一些差异。
Turbopack 的底层架构确保编译时间的差异更加一致。路由的编译时间仅变化几个百分点,这使我们能够持续优化编译器性能。
与生产环境高度一致的开发构建
为了使用 webpack 优化编译速度,我们不得不接受一些权衡,这些权衡导致了开发环境和生产环境的分歧。这些权衡的一些示例是我们使用 style-loader
,它将样式注入到页面中并允许 Fast Refresh,而无需重新加载页面。但是,这意味着样式在开发环境中由 JavaScript 注入,这会导致未样式化内容的闪烁。我们解决了这种未样式化内容的闪烁问题,因此您看不到它。另一个示例是,使用 webpack 的 Next.js 使用 eval-source-map
,这意味着所有代码都包装在 eval
中,并且 sourcemap 包含在其中,这确保了 sourcemap 在开发环境中可用,但代价是捆绑的代码更难检查和调试。虽然 webpack 支持使用 source-map
选项输出完整的 sourcemap,但它会对编译时间和内存使用量产生过大的影响。
对于 Turbopack,我们着手默认解决这些问题,输出 CSS 文件和 sourcemap 而不使用 eval
。Turbopack 利用 sections
sourcemap,这是 sourcemap 规范中相对较新的部分,它允许更有效地合并 sourcemap 输出。以前我们必须在一个地方生成所有映射,现在我们能够更精细地生成和缓存它们。
Turbopack 中的 CSS 处理始终输出 CSS 文件,并且与 JavaScript 处理类似,它可以通过 Turbopack 开发运行时的一部分机制更新 CSS 文件,而无需刷新浏览器。
现在我们可以自信地说,当某些东西在 Turbopack 的开发环境中工作时,它在生产环境中也能以相同的方式工作和表现。
我们的第一个稳定版本
两年前,我们在 Next.js 13 中以 alpha 版本的形式推出了 Turbopack,预览了其性能潜力。虽然最初的结果很有希望,但它仅支持基本用法 —— 许多 Next.js 功能(如 basePath
)尚未实现。
在接下来的一年中,我们专注于添加缺失的 Next.js 和捆绑功能。根据社区反馈,我们决定完全专注于 next dev
体验,以便我们可以解决最常见的迭代速度问题。到去年的 Next.js Conf 时,90% 的开发测试都已通过,并且 Vercel 开发人员已经在日常开发中使用 Turbopack。
在四月份,我们宣布 Next.js 14.2 通过了 99.8% 的测试,此后不久达到了 100%。从那时起,我们解决了 GitHub 报告的问题,特别是关于 npm 包、Fast Refresh 和错误位置准确性的问题。
诚然,实现稳定性的道路漫长,但这主要归因于 Next.js 广泛的测试套件,该套件为稳定性设定了很高的标准。我们花了 8 年时间来发现边缘情况并添加了 6,599 个开发测试,这些测试也需要在 Turbopack 中通过。另一个因素是我们设计 Turbopack 时采用了与 webpack 完全不同的架构。简单地将 webpack 移植到 Rust 会更容易,但无法解锁我们想要实现的性能提升。
既然 Turbopack 通过了所有测试,已经通过了顶级 npm 包的验证,并且早期采用者的反馈已得到解决,我们已准备好将其标记为稳定版。
究竟什么是稳定版?
这在过去一直是一个令人困惑的点,因此我们将用本节来阐明此版本为 Next.js 社区解锁了什么。
此版本专门将 next dev --turbo
命令标记为稳定版。生产版本(next build --turbo
)尚不支持,但请继续阅读以获取最新信息,因为它们正在开发中。我们最终计划在 Next.js 之外发布 Turbopack 的独立版本,但我们想首先通过增强 Next.js 社区的体验来证明其价值。
除了我们将在下一节中介绍的不受支持的功能外,Turbopack 应该可以与 Next.js 的所有稳定功能一起使用。为了明确起见,Turbopack 同时支持 App Router 和 Pages Router。实验性功能可能可以或可能无法与 Turbopack 一起使用,但当它们被标记为稳定版时,肯定可以。
如果您的应用程序具有 webpack 自定义,但仅添加了 webpack 加载器,则您可能已经可以通过为 Turbopack 配置加载器来使用 Turbopack。您可以阅读有关 Turbopack 中 webpack 加载器支持的文档。
以下是经过验证可与 Turbopack 一起使用的 webpack 加载器列表
@svgr/webpack
babel-loader
url-loader
file-loader
raw-loader
tsconfig-paths-webpack-plugin
—— 开箱即用,无需插件。- 大多数其他加载器也适用,因为我们支持 webpack 加载器 API 的子集。
大多数 CSS 和 CSS-in-JS 库都受支持
- 受支持
- Tailwind CSS
- @emotion/react
- Sass
- styled-components
- Bootstrap
- Antd
- node-sass
- JSS
- Emotion
- theme-ui (uses Emotion)
- @chakra-ui/core (with Emotion)
- aphrodite
- 当前不支持
- Less —— 您可以添加 less-loader。使用 webpack 的 Next.js 也无法开箱即用地支持 Less。
- @vanilla-extract/css —— 使用自定义 webpack 插件 —— 我们将研究在未来支持所需钩子所需的条件。
- StyleX —— 需要 Babel 转换和对
data:
属性的支持 —— 我们将在next build --turbo
稳定后研究支持 StyleX。
性能
我们想指出,今天发布的版本的性能明显优于 webpack,但这并非最终性能数字。我们一直遵循 Kent Beck 的著名公式“先使其工作,再使其良好,最后使其快速。” 到目前为止,我们的大部分精力都投入到了“先使其工作”阶段,因为我们必须赶上 Next.js 和 webpack 的范围,它们已经成熟了近十年。
Turbopack 大力押注其缓存基础设施,但正如您可能知道的,缓存是软件开发中仅有的两个难题之一。根据经验,我们知道在并非专门为此构建的架构中添加缓存可能会导致不良结果,因此我们为最细粒度的函数也启用了缓存。这意味着重建速度非常快,但代价是冷启动构建和内存使用量较高,我们正在努力实现更好的平衡。 巧妙之处在于,我们可以使用本文前面提到的高级追踪功能来查找低效率之处,并分析哪些函数最值得缓存。
在过去的 3 个月中,我们已经取得了一些重大改进。比较 Next.js 15 RC 2 中的 Turbopack 与 15 RC 1 中的 Turbopack,可以看出这些优化的成果
- 内存使用量平均减少 25-35%。
- 对于包含数千个模块的大型页面,初始编译速度提高 30-50%。
稳定版本的 Turbopack 包含一个内存缓存,每次重启开发服务器时都必须重建该缓存,对于大型应用程序来说,这可能需要 10 秒或更长时间。我们对磁盘持久缓存测试中看到的巨大优势感到非常兴奋,我们将在本文后面介绍这一点。
重大变更
构建我们自己的打包器的主要动机是为了尽可能地匹配 webpack 的现有行为,这是我们当时无法通过任何现有解决方案保证的。这包括文件解析的方式和 webpack 的较小功能,例如 webpackIgnore
注释,一些 npm 包会使用它。
不幸的是,为了使 Turbopack 和相关的 Next.js 实现面向未来,我们不得不删除一些功能。当您使用 webpack 时,仍然会支持这些功能。
有一些重点,让我们深入探讨一下我们不得不更改它们的原因
不支持 webpack()
配置。 Turbopack 不是 webpack,它没有相同的配置选项结构,尽管它确实支持许多相同的功能。具体来说,我们已经实现了对 webpack 加载器 和 解析别名 的支持。大多数转换代码的 webpack 加载器都开箱即用。一些执行特殊操作的 webpack 加载器,例如 webpack 子编译器和发出文件,则不受支持。
.babelrc
不会自动转换代码。 Turbopack 默认利用 SWC。您仍然可以根据需要添加 babel-loader
,但我们正在确保默认设置始终快速,并且这些设置在架构方面也具有意义。即使您配置了 .babelrc
,我们也始终必须运行 SWC,以便处理其他优化。这类似于 webpack 始终必须运行 acorn
解析器以进行进一步优化。如果您在 Turbopack 中使用 SWC 而不是 Babel,我们可以解析一次,并在整个 Turbopack 中端到端地利用相同的抽象语法树 (AST)。
一些较少使用的 CSS Modules 功能。 我们已将 CSS 处理从 PostCSS 切换到 Lightning CSS。 Lightning CSS 是一款速度明显更快的 CSS 编译器,它开箱即用地支持 CSS 转换、压缩和 CSS Modules。 权衡之处在于,一些较少使用的功能不受支持。具体来说,:global
和 :local
伪选择器(它们的函数变体 :global()
和 :local()
仍然有效)、@value
以及 :import / :export
ICSS 规则。它也比其他 CSS 解析器更严格,并且会指出代码中的错误,而不是忽略它们。
在添加 Lightning CSS 的过程中,我们为该项目做出了贡献。例如,我们为 CSS Modules 实现了细粒度的选项,以禁用 CSS grid 前缀和 CSS Modules 的 pure
模式。这使得从 webpack 中的 css-loader 过渡到 CSS Modules 时,更容易采用 Lightning CSS。我们还改进了对不受支持的 CSS Modules 功能的错误提示。
我们感谢 Lightning CSS 的作者和维护者 Devon Govett 在该项目上持续合作。
实验性功能。 由于我们专注于 Turbopack 在 Next.js 中的稳定性,因此我们决定首先关注 Next.js 中可用的稳定功能。
有关完整列表,请参阅文档页面。
路线图
Turbopack 已经取得了长足的进步,但仍有许多工作要做。接下来令人兴奋的两大功能是持久缓存和生产构建。我们预计发布顺序大致如下:
- 持久缓存 — 未来小版本
- 构建 Beta 版 — 未来小版本
- 构建候选发布版 — 未来小版本
- 构建稳定版 — 未来小版本
- 建议在 create-next-app 中用于新应用程序 — 未来小版本
- 当您没有自定义 webpack 配置时,在 Next.js 中默认为 Turbopack — 未来主要版本
虽然 webpack 将保留在 Next.js 中,但我们预计由于 Turbopack 的优势,大多数 Next.js 应用程序都希望使用它。一旦 Turbopack 的生产构建完成,我们将开始支持常用的 webpack 插件。
我们对 Turbopack 的未来发展有初步的计划,但我们希望本文的内容仅限于我们有信心在可预见的未来发布的功能。我们可能只讨论两个功能,但其中包含了很多内容,因此值得深入探讨。
持久缓存(跨重启的快速刷新)
持久缓存意味着存储编译器完成的工作,以便在开发服务器重启或多次生产构建中重复使用。
简而言之,Turbopack 避免重复相同的工作,即使您重启也是如此。
正如在“更快的快速刷新”部分中提到的,我们构建了 Turbo Engine,以确保工作可以并行化和缓存,这样每当您更改文件时,我们只需要运行与该文件更改相关的工作。如果我们可以在重启和打开路由时为您提供这种体验呢? 我们就不必重新进行在上一个开发会话中已经完成的编译工作。 如果我们可以获得快速刷新的好处,但用于打开在以前的开发会话中编译的路由,以及跨多个使用 next build
构建的版本呢?
这正是我们一直在努力的方向:为 Turbo Engine 构建一个新的存储层,该存储层支持将编译工作持久化到磁盘,并在启动开发服务器或再次构建时恢复它。
虽然 webpack 在 Next.js 中默认启用了磁盘缓存,但它有很多限制。值得注意的是,为了使其正常工作,必须从磁盘恢复缓存的很大一部分并将其读入内存。它从来都不像是一个足够细粒度的缓存。 例如,在 Vercel 上的大型应用程序中,我们发现当缓存增长到足够大的大小时,webpack 磁盘缓存甚至可能比从头开始执行所有工作还要慢。
与 webpack 现有的磁盘缓存不同,Turbopack 的持久缓存真正感觉像是跨重启的快速刷新。首次编译需要 10 多秒的路由,一旦编译过一次,从缓存恢复只需不到 500 毫秒。
我们在 Turbopack 的 next build
中也看到了类似的结果,只有更改的文件会被重新编译,其他一切都保持原样。在 next build
采取的多个步骤中,这会将大部分时间从运行编译和打包转移到运行 TypeScript 类型检查。
持久缓存目前仍在开发中,因为我们想先使用我们的内部 Next.js 应用程序进行验证。初步结果非常令人鼓舞,随着我们不断优化这些热点路径,性能会随着时间的推移变得更好。
一旦持久缓存稳定,它将默认启用。启用持久缓存不需要更改您的代码库。
如果您有兴趣测试持久缓存,请联系我们!
生产构建
我们很高兴地分享,我们在使用 Turbopack 实现稳定的生产构建方面取得了实质性进展。目前,我们的 96% 的生产测试都已通过,这是一个巨大的进步。但是,在我们可以自信地推荐 Turbopack 用于大规模生产之前,仍有一些领域需要更多的工作。
与开发相比,生产构建带来了其独特的挑战,我们正在积极努力解决这些挑战。下面,我们将回顾一下已经优化的内容和仍在进行中的内容。
生产优化
正确性
确保正确性对于可靠的生产构建至关重要。以下是当前状态:
- CSS 分块:进行中。此功能对于将 CSS 拆分为更小的块至关重要,从而允许仅为应用程序的每个部分加载必要的 CSS,这有助于减少加载时间并确保 CSS 规则的正确排序。
- 生产 JS 运行时:已完成。这确保 JavaScript 运行时在生产环境中按预期运行,从而提供可靠性和稳定性。
- 基于内容的文件名哈希:尚未实现。基于内容的哈希将允许我们根据内容生成文件名,从而在浏览器中实现更高效的长期缓存。
UX 性能优化
UX 性能是提供快速加载时间和高效资源使用的关键。以下是我们正在努力的方向:
- JS 压缩:已完成。我们已经实现了 SWC Minify,自 Next.js 13 以来,Next.js 已经在 webpack 中使用了它。
- CSS 压缩:已完成。使用 Lightning CSS 进行 CSS 压缩,这对于减小样式表的大小非常重要。
- 全局信息(整个应用程序优化):已完成。Turbopack 可以应用需要有关应用程序中所有路由的数据的优化,例如模块 ID 哈希。
- Tree Shaking:部分完成。进行中。我们对 tree-shaking 提供了部分支持,这有助于消除未使用的代码并减小捆绑包大小。但是,在某些情况下,tree-shaking 尚未完全生效
- 动态导入:Tree shaking 对于动态导入(如使用
next/dynamic
)受到限制。 - 复杂导出:某些类型的导出,例如
export { foo as "string name" }
。 - 非 ES 模块:CommonJS 模块不可进行 tree-shaking。
- Barrel 文件:从 barrel 文件重新导出效率低下,在跳过无副作用模块方面存在限制。
- 碎片化:在某些情况下,tree-shaking 可能会创建过多的碎片,从而导致捆绑包效率低下。
- 动态导入:Tree shaking 对于动态导入(如使用
- 模块 ID 哈希(部分):进行中。模块 ID 哈希已部分实现,但我们正在努力提高性能。一旦完全启用,它将有助于减小最终捆绑包大小。
- 导出名称混淆:进行中。这包括减小导出的名称的大小,以减小最终捆绑包大小。
- Scope Hoisting:尚未实现。Scope hoisting 将通过将较小的 JavaScript 模块合并到单个作用域中来帮助减小捆绑包大小,从而减少开销并提高性能。
- 生产优化的 JS 分块:尚未实现。对 JavaScript 进行分块以最大程度地减少重复对于提高加载性能至关重要,尤其是对于大型应用程序。
敬请期待
我们很高兴能够自信地推荐 next dev --turbo
,并且迫不及待地想听到它如何改善您的开发体验。立即试用,亲身感受性能提升。
这仅仅是开始 — 持久缓存和生产构建即将到来,这将为您的工作流程带来更快的速度和更高的可靠性。
当我们朝着确保正确性和优化性能迈进,以无缝处理甚至最大的应用程序时,我们将分享更多更新。敬请关注未来的版本和改进,我们将努力使 Turbopack 成为开发和生产构建的最佳解决方案。
贡献者
我们感谢成千上万的开发人员参与了 Turbopack Beta 和候选发布阶段的测试、报告问题和验证修复。
此版本由以下团队为您带来: