比 Webpack 快 700 倍的 Turbopack,快在哪?

406 阅读9分钟

Turbopack这一工具是针对 JavaScript 和 TypeScript 进行优化的增量打包工具,由 Webpack 的创建者 Tobias Koppers 携手 Next.js 团队,采用 Rust 语言编写而成。下面,让我们深入探究 Turbopack 的显著优势。

Turbopack 的速度表现

image.png

Turbopack 构建于全新的增量架构之上,旨在为开发者提供极致快速的开发体验。在大型应用场景中,它的更新速度堪称惊人,比 Vite 快 10 倍,相较于 Webpack 更是快达 700 倍。而在规模更大的应用里,其速度优势进一步凸显,通常能比 Vite 快 20 倍。

Turbopack 在启动时间方面同样表现卓越。由于它仅打包开发过程中所需的最少资源,启动速度大幅提升。以一个拥有 3000 个模块的应用为例,Turbopack 仅需 1.8 秒即可启动,而 Vite 则需要 11.4 秒。

Turbopack 速度快的原因

Turbo 引擎的工作原理

Turbopack 的高性能得益于其底层可重用的 Rust 库 ——Turbo 引擎,该引擎支持增量计算。其工作原理如下:在 Turbopack 驱动的程序里,可将某些函数标记为 “需记忆”。当这些函数被调用时,Turbo 引擎会记录函数的调用内容以及返回结果,并将其存储在内存缓存中。

以下是一个简化示例:我们在 api.ts 和 sdk.ts 两个文件中调用 readFile 函数,接着对这些文件进行打包并拼接,最终得到 fullBundle。所有这些函数调用的结果都会被保存在缓存中,以便后续使用。当 sdk.ts 的结果发生变化时,需要重新进行打包和拼接操作。但由于 api.ts 并未改变,此时只需从缓存中读取其结果并传递给 concat 函数即可,避免了重复读取和打包,从而节省了大量时间。

image.png

目前,Turbo 引擎将缓存存储在内存中,这意味着缓存的生命周期与运行进程一致,对于开发服务器(Dev server)而言效果极佳。未来,计划将缓存持久化,可保存到文件系统或像 Turborepo 这样的远程缓存中,实现跨运行和机器的工作记忆功能。这种方式使 Turbopack 在计算应用的增量更新时极为迅速,优化了开发过程中的更新处理,确保 Dev server 能对代码更改做出快速响应。

按要求编译

Turbo 引擎为 Dev server 带来了极快的更新速度,而启动时间也是一个重要考量指标。Dev server 启动越快,开发者就能越早投入工作。要加快启动速度,可从两个方面入手:提高工作效率或减少工作量。Turbopack 采用了减少工作量的策略,即只编译启动所需的代码。

  • 页面级编译:在两三年前的 Next.js 版本中,Dev server 启动前会编译整个应用。从 Next.js 11 开始,改为只编译请求页面上的代码,这虽有一定改进,但仍不够完善。例如,当导航到 /users 页面时,会打包所有客户端和服务端模块、动态导入的模块以及引用的 CSS 和图片。即便页面的大部分内容隐藏在视图之外或选项卡后面,这些内容仍会被编译。
  • 请求级编译:Turbopack 更为智能,它能够仅编译请求的代码。当浏览器请求 HTML 时,它只会编译 HTML,而不会编译 HTML 引用的其他内容;若浏览器需要 CSS,就仅编译 CSS,不编译其引用的图片。甚至,除非 Chrome DevTools 处于打开状态,否则 Turbopack 不会编译 source map。通过这种请求级编译方式,显著减少了请求数量,性能得到大幅提升。

基于 Rust 开发的优势

Turbopack 基于 Rust 开发,Next.js 团队在将基于 JavaScript 的工具迁移至基于 Rust 的工具时,均取得了显著的性能提升。例如,Next.js 用 Rust 替换 JavaScript 编译器 Babel 后,编译速度提高了达 17 倍;替换 Terser 后,压缩速度提高了 6 倍,同时还减少了加载时间和宽带使用。

选择 Turbopack 的理由

开发 Turbopack 的初衷是提升 Next.js 的速度,团队期望它能取代 Webpack,成为下一代 Web 打包工具。那为何不选择新一代打包工具 esbuild 和 swc,而是自主开发 Turbopack 呢?

增量计算

通常,加快进程有两种方式:减少工作量或并行工作。为打造最快的打包工具,团队决定创建一个可重用的 Turbo 构建引擎,以实现分布式和增量行为。Turbo 引擎如同函数调用的调度程序,允许在所有可用内核上并行调用函数,并且会缓存所有调度函数的结果,避免重复执行相同的工作。简而言之,它能以最快速度完成最少的工作。

其他工具在 “做更少的工作” 方面采用了不同策略。例如,Vite 在开发模式下使用原生 ESM 来减少工作量,底层还借助 esbuild 完成许多任务。然而,esbuild 虽打包速度极快,但存在一些不足:它的代码针对快速打包进行了超优化,缺乏热更新(HMR)功能;并且缓存机制不完善,会导致大量重复工作。相比之下,基于 Rust 且具备增量计算能力的 Turbopack 在大规模项目中表现更为出色。

惰性打包

Next.js 的早期版本在开发模式下尝试打包整个 Web 应用,这种方式效率较低。现代版本的 Next.js 仅打包 Dev server 请求的页面,例如访问 localhost:3000 时,只会打包 pages/index.jsx 及其导入的模块。这种 “惰性” 方法是实现快速 Dev server 的关键。

而 esbuild 缺乏 “惰性” 打包的概念,采用全有或全无的方式。Turbopack 的开发模式会根据收到的请求构建应用导入和导出的最小图,仅打包必要的最少代码。这一策略使 Turbopack 在首次启动 Dev server 时速度极快,只需计算渲染页面所需的代码,并将其以单个块的形式发送到浏览器。在大规模应用中,这种方式比原生 ESM 快得多。

Turbopack 的功能特性

构建 Web 应用的实践方式丰富多样,仅 CSS 就涉及 SCSS、Less、CSS Module、PostCSS 等多种类型,React、Vue 和 Svelte 等框架也需要定制化设置。

在开发打包工具时,团队希望 Turbopack 能够开箱即用,同时可通过插件扩展功能。目前,Turbopack 仍处于 alpha 阶段,暂时无法进行配置,插件功能也尚未开放。以下是 Turbopack 默认配置中已具备的功能以及未来计划通过插件实现的功能:

  • JavaScript:支持所有 ESNext 功能、Browserslist 和顶层 await。
  • TypeScript:原生支持 TypeScript,包括路径解析和 baseUrl 设置。
  • Imports:支持 require、import、动态导入等多种导入方式。
  • Dev Server:优化后的 Dev Server 支持热更新(HMR)和快速刷新。
  • CSS:支持全局 CSS、CSS Module、postcss - nested 和 @import。
  • 静态资源:支持 /public 目录、JSON 导入和通过 ESM 导入资源。
  • 环境变量:通过 .env、.env.local 等文件支持环境变量配置。

Turbopack 与 其它前端打包工具对比

构建模式增量构建官方网站
Turbopack极快,大型应用更新速度比 Vite 快 10 倍,比 Webpack 快 700 倍;启动时间短,3000 个模块的应用仅需 1.8 秒启动集成在 Next.js 较易上手,独立使用配置有一定难度尚在发展中,目前插件等支持有限大型项目频繁迭代开发,对构建速度要求极高的场景支持,速度快JavaScript、TypeScript开发模式按需编译,生产模式优化极致的增量构建速度,能快速响应代码变更turbo.build/pack
Rspack快,采用 Rust 优化核心模块,编译和内存利用高效兼容 Webpack 配置,迁移成本低,有 Webpack 经验者易上手处于发展阶段,在逐步完善,插件生态有 Webpack 基础习惯 Webpack 开发模式团队接手的大型项目,对打包性能有较高要求的企业级应用支持JavaScript、TypeScript 等类似 Webpack,支持多种构建模式有较好的增量构建能力www.rspack.dev/
Vite快,开发模式利用 ES 模块浏览器原生支持,冷启动速度极快相对简单,配置直观易懂生态发展良好,但成熟度略逊于 WebpackVue 项目开发,追求快速开发反馈、对开发速度要求高的项目迭代支持,热更新体验好JavaScript、TypeScript、Vue 等开发模式基于原生 ESM,生产模式借助 Rollup 打包增量更新速度较快vitejs.dev/
Webpack性能因配置和项目规模而异,大型项目冷启动和增量构建相对较慢复杂,学习曲线陡峭,需深入理解配置项极其丰富,有大量插件和 loader 可供使用各种规模项目,尤其是大型企业级项目,定制化需求高的场景支持,但大型项目更新速度较慢JavaScript、CSS、图片等多种资源支持多种构建模式,可精细配置有增量构建能力,但速度在大型项目中不占优webpack.js.org/
esbuild极快,利用多核 CPU 并行处理,能快速完成 JavaScript 和 CSS 编译简单,配置项少插件生态不够成熟对构建速度要求极高的项目,开发过程中需要频繁重新打包的场景部分场景支持,但无完善 HMR 机制JavaScript、TypeScript、CSS 等专注快速打包增量构建支持不足esbuild.github.io/

Turbopack 的未来展望

目前,Turbopack 已可在 Next.js v13 中使用。未来,它将发布独立的命令行界面(CLI)和插件 API,并支持 Svelte 和 Vue 等其他框架。Turbopack 将应用于 Next.js 13 的 Dev server,为闪电般快速的热更新(HMR)提供支持,原生支持 React 服务端组件以及 TypeScript、JSX、CSS 等。对于 Webpack 用户而言,也有望通过 Turbopack 实现向基于 Rust 的未来开发模式的增量迁移。

我们有理由期待,在 Webpack 的创建者 Tobias Koppers 的引领下,Turbopack 能够成为 Web 开发领域的下一代主流打包工具。