CI 上的构建缓存要来回搬两趟:构建完打包上传,下一条流水线开头再拉回来解压。目录越大,两头耗得越久,碰上 runner 网络一般,搬运的工夫有时能把省下的编译时间吃掉不少。Rspack 2.3 带的那套新缓存,瞄准的正是占用大、写得慢这两件事。
官方给的数字
这些数字都出自 10 月 29 日的官方博客 Announcing Rspack 2.3,是他们自己的基准测试,换个项目结果会不一样。博客写的是,新缓存让磁盘占用下降约 79%,冷构建时的峰值内存减少约 16%。热构建则稍微慢了一点。
省空间的原因博客也讲了。旧缓存保存整个构建阶段的中间状态,模块之间的关系也一并写进去,文件大,恢复时容易出错。新实现只存单个任务(像一次模块构建)的结果,写盘前的准备工作挪到空闲时段或者最后收尾阶段,不再卡着编译。
怎么开
experiments 配置文档里,experiments.newCache 标着 Stability: Experimental,默认值是 false。持久化缓存要这样写:
export default {
cache: {
type: 'persistent',
},
experiments: {
newCache: true,
},
};
newCache 也能传对象,按阶段开关:codeGeneration、module、devtool、loader、minimize 默认都是开的,只有 resolver 是关的。实验性的东西后面可能改名或调整,升级 Rspack 时留意 changelog,lockfile 里把版本锁住。
CI 上要多想几步
- 文档写明 production 和 none 模式下
cache默认是false,CI 一般跑生产构建,不显式配置就等于没开缓存,新旧实现都一样。 - 新实现暂不支持
cache.portable和cache.maxAge。前者让缓存能跨平台、跨路径共用,靠它在多台机器间搬运的项目,眼下还开不了新实现。后者在现有实现里默认清掉 7 天没被访问的缓存目录。切换以后,过期清理大概只能交给 CI 那边的策略。 - 默认存放目录是
node_modules/.cache/rspack,CI 里配的缓存路径要对上,key 最好带上 lockfile 的哈希。 - CI 把缓存恢复回来以后跑的那一次,本身就算热构建。磁盘上省下的空间换来上传下载变快,热构建又慢一点,两头能不能抵得过,只有实测知道。
babel-loader、less-loader 这类转换开销大的项目,可以顺带试试单个 loader 的缓存:开了新缓存后,在 module.rules 的 use 项里加 cache: true。它的失效条件单独计算:整体配置改了,只要这个 loader 自己的输入、选项和依赖不动,结果照样能复用。博客里用 babel-loader 处理约一万个模拟模块,关掉并行 loader 时,开缓存把耗时从 63.8 秒压到 11.2 秒。
怎么测
冷跑、热跑各三次:冷跑前清空缓存目录,热跑时保留它。每回记下耗时、峰值内存和占用空间,CI 上再加一项上传下载用掉的时间。Linux 上用 /usr/bin/time -v 看 Maximum resident set size,目录大小用 du -sh。新旧实现各测一轮,数字摆在一起就好判断了。
测完大致能分成几种情况。缓存目录大、上传下载占了流水线不少时间,或者 runner 内存比较紧的,新实现可以早点上,冷构建时省下的那 16% 峰值在小规格机器上也有用。依赖 cache.portable 跨机器共用缓存的,等官方补上支持再说。缓存本来就小、流水线大部分时间花在测试上的,换不换差别不大,没必要给自己加一个实验开关。
本地开发也可以单独看。dev 模式下 cache 默认就是内存缓存,要不要在本地也开持久化加新实现,看你平时重启 dev server 的频率。一天要来回折腾好多回的话,热构建慢的那一点会天天碰到,可以先只在 CI 的配置里打开。
这个版本还换上了 SWC Next 解析器,跟缓存是两回事,这里不展开。官方说打算在之后的某个小版本里把新缓存设为默认。
有在 CI 上试过的吗,缓存目录实际小了多少?