取代Webpack的打包工具Turbopack究竟有多快

2022-11-11 18:23:43 浏览数 (1)

一、Turbopack简介

10 月 25 日,Next.js 13 正式发布。同时,Vercel 还推出并开源了下一代打包工具:Turbopack。Turbopack 是针对 JavaScript 和 TypeScript 优化的增量打包工具,由 Webpack 的创建者 Tobias Koppers 和 Next.js 团队使用 Rust 编写。Turbopack 的推出吸引了众多前端开发者的关注,并且Turbopack具有如下一些优势。

1.1 Turbopack功能特性

构建 Web 应用的方案非常多,仅在 CSS 中,就有 SCSS、Less、CSS Module、PostCSS等,并且,如果使用React、Vue 和 Svelte 等前端框架,还可以自定义配置。而在构建打包工具时,我们希望它能开箱即用,无需在添加额外的配置。目前,Turbopack 仍处于 alpha 阶段,在当前状态下,Turbopack 还不支持配置,所以插件也还不可用。

下面来看一下 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 等支持环境变量。

1.2、Turbopack有多快

Turbopack 建立在新的增量架构上,以提供最快的开发体验。在大型应用上,它的更新速度比 Vite 快 10 倍,比Webpack 快 700 倍。在更大的大型应用上,也会比Vite快 20 倍。

由于 Turbopack 只打包开发所需的最少资源,因此启动时间非常快。在具有 3000 个模块的应用上,Turbopack 需要 1.8 秒即可启动,而 Vite 则需要 11.4 秒:

并且,在Dev server 启动时间和代码更新方面,Turbopack也是明显优于Vite。

1.2.1 Dev server 启动时间

Turbopack 的 Dev server 启动速度比 Vite 快得多。在 1000 个模块的应用中,Vite 需要 4.8 秒才能启动。Turbopack 启动仅需 0.9 秒,快了5.5倍。在大型应用中,这种差异将保持一致。在 30000 个模块的应用中,Turbopack 需要 1.8 秒即可启动,而 Vite 则需要 11.4 秒, Turbopack 的启动速度比 Vite 快了 5.4 倍。

1.2.2 代码更新

当文件发生更改时,我们一般需要将更改编译后再呈现给浏览器。编译打包做到的越快,发布的速度就越快。在 1000 个模块的应用中,Turbopack 对文件更改的速度比 Vite 快 5.8 倍。

1.3 为什么快

Turbopack 性能的秘诀有两个:高度优化的机器代码和低层级增量计算引擎,可以缓存到单个函数的级别。它的架构吸取了 Turborepo 和 Google 的 Bazel 等工具的经验教训,它们都专注于使用缓存来避免重复执行相同的工作。

1.3.1 Turbo 引擎

urbopack 之所以如此之快,是因为它建立在一个可重用的 Rust 库之上,该库支持增量计算,称为 Turbo 引擎。其工作原理是:在 Turbopack 驱动的程序中,可以将某些函数标记为“to be remembered”。当这些函数被调用时,Turbo 引擎会记住它们被调用的内容,以及它们返回的内容,然后将其保存在内存缓存中。下面是一个简化的示例:

首先,我们在api.ts​和sdk.ts​这两个文件中调用readFile,然后打包这些文件,将它们拼接在一起,最后得到 fullBundle。同时,所有这些函数调用的结果都保存在缓存中以备后用。

由于sdk.ts​的结果发生了变化,所以需要再次打包并执行资源的再次拼接。需要注意的是,api.ts​并没有改变,只需从缓存中读取它的结果并将其传递给concat即可。这样设计的好处是不需要重新打包来节省了时间。

Turbopack 是建立在 Turbo 之上的,Turbo 是基于 Rust 的开源、增量记忆化框架。Turbo 可以缓存程序中任何函数的结果。当程序再次运行时,函数将不会重新运行,除非它的参数改变了。这种粒度的架构使您的程序能够在函数级别跳过大量工作。

1.3.2 缓存

目前,Turbo引擎将缓存存储在内存中,这意味着缓存的时间与运行它的进程一样长,这对开发服务器来说是很好的,不必每次运行都由服务器进行处理。默认情况下,Next v13 会启动 Turbo引擎的缓存,如果手动取消开发服务器缓存,那么Turbo缓存也会被清空。

在未来,官方还计划将这个缓存持久化到文件系统或者像 Turborepo 那样的远程缓存中,这将意味着 Turbopack 可以在不同的运行和机器上记住所做的工作。这种方法使得 Turbopack 在处理应用程序的增量更新时非常快,开发服务器进而将对变化作出迅速的反应。

1.3.3 按要求编译

Turbo 引擎有助于在 开发服务器上提供快速地更新,但有另一个重要指标需要考虑:启动时间。开发服务器开始运行的速度越快,开始工作的速度就越快。通常,有两种方法可以使流程更快:工作更快或者工作更少。对于启动一个开发服务器来说,减少工作量的方法就是只编译启动所需的代码。

页面级编译

2-3 年前,Next.js在启动应用前会编译整个应用。不过,从Next.js 11 开始,就只编译请求的页面上的代码,带来的直接好处是编译会更快。不过,Next.js 11的解决并不完美,简单的说,当导航到/users时,将打包所有客户端和服务端模块、动态导入的模块以及引用的 CSS 和图片。这意味着如果页面的很大一部分隐藏在视图之外,或者隐藏在选项卡后面仍然会编译它。

请求级编译

Turbopack 足够智能,可以只编译请求的代码。这意味着如果浏览器请求 HTML,就只会编译 HTML,而不会编译 HTML 引用的任何内容。如果浏览器需要 CSS,将只编译 CSS,而不编译其引用的图片,Turbopack 甚至知道不编译 source map,除非 Chrome DevTools 是打开的。通过请求级编译,减少了请求的数量,性能方面改进显着。

二、快速上手

2.1 初始化项目

Turbopack目前还处于alpha版本,只是Next 13提供的技术支持。按照官方文档所述,我们只需执行如下命令即可完成Turbopack项目的初始化。

代码语言:javascript复制
npx create-next-app --example with-turbopack

接下来,就是等待项目的构建,如下图。

2.2 启动项目

接下来,我们打开项目,然后执行package.json中的dev指令,即可启动项目。启动的方式针对构建工具的不同,运行的命令也会不同。

代码语言:javascript复制
npm run dev //npm
yarn dev    //yarn
pnpm dev    //pnpm

启动成功后,系统会给出如下的提示:

代码语言:javascript复制
Thank you for trying Next.js v13 with Turbopack! As a reminder,
Turbopack is currently in alpha and not yet ready for production.
We appreciate your ongoing support as we work to make it ready
for everyone.


Learn more about Next.js v13 and Turbopack: https://nextjs.link/with-turbopack
Please direct feedback to: https://nextjs.link/turbopack-feedback


ready - started server on 0.0.0.0:3000, url: http://localhost:3000
event - initial compilation 13ms
event - updated in 2161ms

接着,我们打开http://localhost:3000就可以看到效果,如下图。

2.3 Dev环境下响应较慢

项目在启动速度方面还是挺快的,只需要几十毫秒,首屏加载也很快,但是当我在页面上切换菜单时,发现就有一点卡。下图是我点击卡片,获取的的响应时间日志。

2.4 项目打包

我们知道,任何项目上线之前,都要执行项目打包操作。关于打包,我们可以直接执行下面指令打包。

代码语言:javascript复制
yarn run build

打包成功后,执行start指令,即可启动项目。

代码语言:javascript复制
yarn run start

项目启动后,再次切换菜单栏时,会发现响应速度非常的快,一点也感觉不到卡,大概是Dev环境是开启了很多的监控工具。

三、Turbopack 的未来

目前,Turbopack还处于alpha阶段,只能在 Next.js v13 中使用。未来,Turbopack将发布独立的 CLI、插件 API,以及开启对Svelte 和 Vue等框架的支持。并且,Turbopack 将用于 Next.js 13 Dev server。它将为闪电般快速的 HMR 提供动力,并将原生支持 React 服务端组件,以及 TypeScript、JSX、CSS 等。Webpack 用户还可以期待使用 Turbopack 进入基于 Rust 的未来的增量迁移路径。

我们衷心的期待在 Webpack 的创建者 Tobias Koppers 的带领下,将Turbopack 建设成为 Web 的下一代打包工具。

文档链接:https://github.com/vercel/turbo

0 人点赞