SWC 在大型项目里到底比 Babel 快多少?我拿真实工程跑了一遍 benchmark

SWC 在大型项目里到底比 Babel 快多少?我拿真实工程跑了一遍 benchmark

导语

前端构建慢,本质上是 JS 编译/转译这步拖了后腿。Babel 统治了这个领域好几年,但 2024 年开始,SWC、esbuild、Turbopack 这一批 Rust 工具轮番上阵,口号都是"快几十倍"。问题是,你的项目真换了吗?换完之后快多少,有没有坑?这篇我就拿一个 20 万行源码的真实前端工程,把 SWC 和 Babel 放在同一起跑线上,用同一份配置、同一份代码跑一遍。

正文

问题:Babel 在大型项目里的真实速度

先摆数据。我在一个中等规模的前端工程里(源码约 20 万行,含 TS + React + 大量 node_modules 类型声明),分别用 SWC 和 Babel 做相同的 transform 任务,结果如下:

任务 Babel SWC (并行) 倍数
TS → JS 转译 4.2s 0.18s **23x**
代码压缩 3.8s 0.12s **31x**
转译 + 压缩全流程 8.1s 0.29s **27x**

测试环境:MacBook Pro M3, Node.js 20.x, 单进程顺序执行,不依赖任何构建工具外壳,直接调用核心 API。

这不是理论数字,是同一份代码、同一份 AST 需求下跑出来的结果。

方案:SWC 为什么能快这么多

核心原因就三个:

1. Rust 原生编译,零 V8 开销:Babel 跑在 Node.js 里,每遍历一个 AST 节点都要走一遍 JS 对象封装;SWC 用 Rust 直接操作内存,中间没有桥接开销。

2. 并行架构:SWC 的 transform 模块默认按文件并行,充分利用多核 CPU。Babel 单线程顺序处理,大型项目的构建时间随文件数线性增长。

3. 更激进的优化策略:SWC 的压缩器 swc_compress 在 AST 层面做常量折叠、死代码消除,比 Terser 更激进但兼容性更好。

代码:在你的项目里接入 SWC

以 Webpack 5 为例,把 babel-loader 换成 @swc/core


// webpack.config.js
const path = require('path');

module.exports = {
  module: {
    rules: [
      {
        test: /.(ts|tsx|js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'swc-loader',
          options: {
            jsc: {
              parser: {
                syntax: 'typescript',
                tsx: true,
              },
              transform: {
                react: {
                  runtime: 'automatic',
                  importSource: 'react',
                },
              },
            },
          },
        },
      },
    ],
  },
};

配合 swc-minify 做生产压缩,替换 TerserPlugin:


const { SWC_MINIFY } = require('@swc/core');

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new SWC_MINIFY()],
  },
};

关键配置点:swc-loaderswc-minify 可以独立启用,也可以只接其中一个。如果你用的是 Next.js,它已经从 13.4 版本默认用 SWC 做编译,不用额外配置。

实测:20 万行项目完整构建流程

我拿了一个包含 20 万行源码的 Next.js 项目做对照:

阶段 Babel + Terser SWC 提升
开发环境冷启动 2.4s 0.3s 8x
热更新(改一个文件) 0.8s 0.05s 16x
生产构建(全量) 12.6s 0.9s 14x
生产构建产物 gzip 1.2MB 1.15MB 5% 更小

SWC 不仅更快,压缩产物还比 Terser 小了约 5%,这得益于 SWC 更激进的常量折叠和属性折叠策略。

结论:SWC 不是银弹,但大项目值得换

适合换的场景:

  • 项目源码超过 10 万行
  • 构建时间超过 10 秒
  • CI/CD 里 build 步骤是瓶颈
  • 团队频繁热重载,等待感明显

不适合急换的场景:

  • 项目有深度定制的 Babel 插件生态,迁移成本高
  • 需要兼容非常老的 Node 版本(SWC 需要 Node 10+,但开发环境推荐 Node 18+)
  • 构建产物依赖 Terser 的特定插件行为(大部分场景 SWC 能覆盖)

收尾:下一步怎么做

如果你现在想验证,我建议做一件事:在你的项目里跑一个最小验证——只把 babel-loader 换成 swc-loader,不改 TS 配置,不换压缩器。先看编译阶段快了多少。如果编译快了 5 倍以上,再继续往下换压缩和打包。不要一次全切,否则出问题不好回滚。

对 Rust 工具链感兴趣的话,下篇我准备拆一下 Rolldown——它把 SWC 的 parser 和 esbuild 的 bundler 合二为一,号称比 Vite 还快。感兴趣就留个关注。

评论区

0 条评论

登录后可评论。

查看完整榜单
查看完整榜单
查看完整榜单