性能分析

本章节介绍 Rspack 中一些常见的性能瓶颈和性能分析方法。

使用 Rsdoctor 分析

Rsdoctor 是一个针对 Rspack 的构建分析工具,可以直观地展示构建过程,例如编译时间、编译前后的代码变化、模块引用关系、重复模块等。

请参考 使用 Rsdoctor 了解更多。

Rspack profile

Rspack CLI 支持使用 RSPACK_PROFILE 环境变量来进行构建性能分析。

RSPACK_PROFILE=ALL rspack build

该命令会生成一个 .rspack-profile-${timestamp}-${pid} 文件夹,该文件夹下会包含 trace.json 文件,该文件由 Rspack 基于 tracing 细粒度地记录了 Rust 侧各个阶段的耗时,可以使用 ui.perfetto.dev 进行查看。

查看 Tracing 了解更多。

性能瓶颈

尽管 Rspack 本身提供的构建性能已经足够优秀,但在 Rspack 中使用一些 JavaScript 编写的 loaders 和 plugins 时,它们可能会导致整体的构建性能劣化,尤其是在大型项目中。

对于这类问题,有一部分可以通过 Rspack 内置的高性能替代方案来解决,另一部分可以通过性能分析工具来定位,从而采取针对性的优化。

下面是一些常见的案例:

babel-loader

babel-loader 基于 Babel 来编译 JavaScript 和 TypeScript 代码,可以将 Babel 替换为更快的 SWC。Rspack 内置了 builtin:swc-loader,它是 swc-loader 的 Rust 版本,旨在提供更优的性能。

如果你需要使用 Babel 插件实现自定义的转换逻辑,可以在配置 babel-loader 时使用 Rule.include 来匹配尽可能少的文件,以减少 Babel 编译的开销。

postcss-loader

postcss-loader 基于 PostCSS 来编译 CSS 代码,通常会配合 PostCSS 插件进行 CSS 语法降级、添加浏览器前缀等,可以将 PostCSS 替换为更快的 Lightning CSS,使用 Rspack 内置的 builtin:lightningcss-loader 即可。

terser-webpack-plugin

terser-webpack-plugin 基于 Terser 来压缩 JavaScript 代码,可以将 Terser 替换为更快的 SWC minimizer,使用 Rspack 内置的 SwcJsMinimizerRspackPlugin 即可。

css-minimizer-webpack-plugin

css-minimizer-webpack-plugin 基于 cssnano 等压缩工具来压缩 CSS 代码,可以将 cssnano 替换为更快的 Lightning CSS minimizer,使用 Rspack 内置的 LightningCssMinimizerRspackPlugin 即可。

less-loader

less-loader 基于 Less 来编译 .less 文件,由于 Less 目前没有官方实现的高性能替代方案,建议使用 sass-loadersass-embedded 代替,sass-embedded 是 Sass 原生 Dart 可执行文件的 JavaScript wrapper,具备出色的性能。

html-webpack-plugin

html-webpack-plugin 在生成大量 HTML 文件时,性能表现不佳,Rspack 基于 Rust 实现的 HtmlRspackPlugin 可以提供更好的性能。

线程池大小

Rspack 在内部使用一个专门的线程池来执行文件系统读写等阻塞操作,以避免阻塞主线程。

默认情况下,这个线程池的大小是 4,与 Node.js 的 libuv 保持一致,能在大多数开发与 CI 环境中提供稳定性能。

如果你的构建环境使用高速存储,可以通过设置 RSPACK_BLOCKING_THREADS 环境变量来修改线程数,以获得更高的并发度和潜在的性能提升,例如:

# 需要安装 cross-env 包来设置环境变量
cross-env RSPACK_BLOCKING_THREADS=8 rspack build

设置环境变量后,可以观察构建时间的变化,以找到最合适的配置。

在较慢或延迟较高的文件系统中,建议保留默认值甚至更低,以避免线程争用。