当前位置: 首页 > 科技观察

比Webpack快700倍的Turbopack在哪里?

时间:2023-03-17 17:56:24 科技观察

大家好,我叫CUGGZ。10月25日,Next.js13正式发布。同时,Vercel还推出并开源了下一代打包工具:Turbopack。Turbopack是一个针对JavaScript和TypeScript优化的增量打包工具,由Webpack的创建者TobiasKoppers和Next.js团队用Rust编写。Turbopack的推出引起了众多开发者的关注。一起来看看Turbopack的优势吧!Turbopack有多快?Turbopack建立在新的增量架构之上,以提供最快的开发体验。在大型应用程序上,它的更新速度比Vite快10倍,比Webpack快700倍。在大型应用程序上通常比Vite快20倍。由于Turbopack仅打包开发所需的最少资源,因此启动时间非常快。在有3000个模块的应用程序上,Turbopack需要1.8秒才能启动,而Vite需要11.4秒:为什么Turbopack这么快?Turbopack性能的秘诀是双重的:高度优化的机器代码和可以缓存到单个函数级别的低级增量计算引擎。它的架构借鉴了Turborepo和Google的Bazel等工具,这两个工具都专注于使用缓存来避免重复执行相同的工作。Turbo引擎如何工作Turbopack之所以如此之快,是因为它建立在支持增量计算的可重用Rust库之上,称为Turbo引擎。这是它的工作原理。在Turbopack驱动的程序中,某些函数可以被标记为“被记住”。当调用这些函数时,Turbo引擎会记住它们被调用的内容以及返回的内容。然后它将它保存在内存缓存中。这是一个简化的例子:我们首先在两个文件中调用readFile,api.ts和sdk.ts。然后将这些文件打包,拼接在一起,最后得到fullBundle。所有这些函数调用的结果都保存在缓存中以备后用。由于sdk.ts的结果变了,需要重新打包,然后重新拼接。重要的是,api.ts没有改变。只需从缓存中读取其结果并将其传递给concat。因此,通过不阅读和重新包装可以节省时间。Turbo引擎当前将其缓存存储在内存中。这意味着缓存将与运行它的进程一样长地存在,这对开发服务器很有效。将来,计划将此缓存保留到文件系统或远程缓存(如Turborepo)。这意味着Turbopack可以记住跨运行和跨机器完成的工作。这种方法使Turbopack在计算应用程序的增量更新时速度非常快,Turbopack经过优化以处理开发中的更新,这意味着开发服务器将始终快速响应更改。按需编译Turbo引擎有助于在开发服务器上提供极快的更新,但还有另一个重要指标需要考虑——启动时间。开发服务器开始运行的速度越快,它开始工作的速度就越快。有两种方法可以使过程更快:工作更快或做更少的工作。为了启动Dev服务器,减少工作量的方法是只编译启动需要的代码。(1)页面级编译2-3年前的Next.js版本会在显示Devserver之前编译整个应用。从Next.js11开始,只编译请求页面上的代码。这更好,但并不完美。当导航到/users时,所有客户端和服务器模块、动态导入的模块以及引用的CSS和图像都被捆绑在一起。这意味着如果页面的很大一部分隐藏在视图之外,或者隐藏在选项卡后面,它仍然可以编译。(2)请求级编译Turbopack足够聪明,只编译请求的代码。这意味着如果浏览器请求HTML,则只会编译HTML,而不是HTML引用的任何内容。如果浏览器需要CSS,它只会编译CSS,而不是它引用的图像,Turbopack甚至知道除非ChromeDevTools打开,否则不会编译源映射。通过请求级编译,减少请求次数,显着提升性能。为什么要在Rust上开发?Turbopack是在Rust之上开发的,每次Next.js团队将基于JavaScript的工具转移到基于Rust的工具时,他们都会看到巨大的改进。Next.js取代了JavaScript编译器Babel,编译速度提高了17倍,Terser压缩速度提高了6倍,同时还减少了加载时间和带宽使用。为什么选择Turbopack?Turbopack的创建是为了提高Next.js的速度,希望它能取代Webpack成为下一代Web打包工具。那么为什么不选择新一代打包工具esbuild和swc,而是选择创建自己的打包工具呢?增量计算通常,有两种方法可以加快进程:减少工作量或并行工作。要构建最快的打包工具,请用力拉动两个杠杆。因此决定为分布式和增量行为创建一个可重用的Turbo构建引擎。Turbo引擎的工作方式类似于函数调用的调度程序,允许在所有可用内核上并行调用函数。Turbo引擎还缓存它调度的所有函数的结果,这意味着它永远不需要执行相同的工作两次。简而言之,它以最快的速度做最少的工作。其他工具采用不同的方法来“减少工作量”。例如,Vite通过在开发模式下使用原生ESM来最小化工作量。在底层,Vite使用esbuild来完成许多任务。esbuild是一个非常快速的打包器,不会强迫我们使用原生ESM。但出于几个原因,决定不使用esbuild:esbuild的代码针对一项任务进行了超优化——快速打包,因此没有HMR(热更新);esbuild是一个非常快的打包工具,但是它并没有做太多的缓存。这意味着大量的重复工作;并且具有增量计算的Rust驱动的捆绑器可以在更大的范围内比esbuild执行得更好。惰性打包Next.js的早期版本试图在开发模式下打包整个Web应用程序,这是次优的。现代版本的Next.js只打包开发服务器请求的页面。例如,如果你转到localhost:3000,它只会打包pages/index.jsx和它导入的模块。这种更“懒惰”的方法是快速开发服务器的关键。而且esbuild没有“惰性”打包的概念——要么全有要么全无。Turbopack的开发模式根据收到的请求构建应用程序导入和导出的最小图形,并且只打包必要的最少代码。这种策略使得Turbopack在第一次启动Dev服务器时速度非常快。只需计算呈现页面所需的代码并将其一次性发送到浏览器即可。在规模上,这最终比原生ESM快得多。这就是构建Turbopack的原因。Turbopack的特性构建Web应用程序的实践非常多样化。仅在CSS中,就有SCSS、Less、CSSModule、PostCSS等。React、Vue和Svelte等框架需要自定义设置。在构建打包工具时,我们希望它开箱即用,无需配置,并通过插件提供一些功能。目前,Turbopack仍处于alpha阶段,在当前状态下,Turbopack尚不可配置,因此插件尚不可用。我们来看看Turbopack默认配置中哪些功能是开箱即用的,哪些功能未来会通过插件配置:JavaScript:支持所有ESNext功能,Browserslist和top-levelawait;TypeScript:开箱即用地支持TypeScript,包括解析路径和baseUrl;导入:支持require、import、动态导入等;DevServer:优化的DevServer支持热更新(HMR)和快速刷新;CSS:支持全局CSS、CSSModule、postcss-nested和@import;静态资源:支持/public目录,JSON导入,通过ESM导入资源;环境变量:通过.env、.env.local等支持环境变量。TurbopackvsVitevsWebpackTurbopackvsViteTurbopack在以下两个关键指标上优于Vite。(1)Devserver启动时间Turbopack的Devserver启动速度比Vite快很多。在1000个模块的应用中,Vite需要4.8秒才能启动。Turbopack仅需0.9秒即可启动,速度提高了5.5倍。在大型应用程序中,这种差异将保持一致。在30,000个模块的应用中,Turbopack的启动速度是Vite的5.4倍。(2)代码更新当文件发生变化时,需要将变化呈现给浏览器。它做的越快,反馈环路越紧密,发布速度越快。在1000个模块的应用程序中,Turbopack进行文件更改的速度是Vite的5.8倍。Turbopack与WebpackTurbopack的增量架构在以下两个关键指标上优于Webpack。(1)Devserver启动时间Turbopack的Devserver启动速度比Webpack快很多。Next.js12在后台使用Webpack,可以在3.4秒内在具有1000个模块的应用程序上启动构建服务器。Turbopack启动速度快0.9秒-快3.9倍。(2)代码更新在Dev服务器上执行的最常见的操作是更改文件。当文件更改时,它需要将更改呈现给浏览器。它做的越快,反馈环路越紧密,发布速度越快。在1000个模块的应用程序中,Turbopack对文件更改的反应速度比Webpack快8.9倍:Turbopack的未来截至目前,Turbopack在Next.jsv13中可用。未来将发布独立的CLI、插件API以及对其他框架(如Svelte和Vue)的支持。Turbopack将用于Next.js13开发服务器。它将为闪电般快速的HMR提供支持,并将原生支持React服务器端组件,以及TypeScript、JSX、CSS等。Webpack用户也可以期待使用Turbopack进入未来基于Rust的增量迁移路径。期待Turbopack在Webpack创建者TobiasKoppers的领导下成为下一代Web打包工具。参考:https://vercel.com/blog/turbopackhttps://turbo.build/