Skip to content
My Blog
Go back

把 CI 构建从 90 秒降到 12 秒

先说结论:PR 的 CI 反馈时间从 92 秒降到 12 秒,改动只有三处——缓存 key、一个 postinstall 脚本、任务编排。没有换工具链。

先测量

动手前先看 CI 自带的分步耗时,取一周的中位数:

阶段耗时占比
依赖安装41s45%
typecheck17s18%
单元测试14s15%
lint12s13%
构建8s9%

另外两个数据:缓存命中率 31%;五个 job 全部串行。这两个数字基本解释了全部问题。

依赖安装:41s → 5s

缓存命中率低的原因藏在 key 里——key 混入了 commit SHA,等于每个提交都强制冷缓存。改成 lockfile 的 hash 后,lockfile 不变就一直命中,命中率稳定在 96%。

# 之前:每个提交都 miss
cache:
  key: deps-${{ github.sha }}

# 之后:lockfile 不变就一直命中
cache:
  key: deps-${{ hashFiles('pnpm-lock.yaml') }}
  paths: [.pnpm-store]

其次是删掉一个 postinstall 脚本(生成版本号文件)。它只被构建用到,挪进了构建 job,安装路径上少了一次 node 进程启动和文件写入。

改完后命中缓存的安装约 5 秒,冷缓存 38 秒。

并行与关键路径

lint、typecheck、单元测试互不依赖,改成并行。串行时总耗时是五段之和,并行后关键路径只剩最慢的一段。

构建挪出 PR 流水线,合并到 main 后再跑。PR 需要回答的是「这个提交能不能合」,不是产出制品。

结果

指标之前之后
PR 反馈时间92s12s
缓存命中率31%96%
合并后构建含在 PR 内31s
每周 CI 总时长4.2h1.1h

12 秒的构成:安装 4s + 并行 job 里最慢的 8s。冷缓存时 PR 反馈约 48 秒,一个月碰不上几次。

没做的事

先测量再动手的价值在这里:三处改动覆盖了 80% 的耗时,剩下 20% 的候选方案全部收益不足、复杂度有余。


Share this post:

Next Post
第 01 课 · 跑起来:三种运行形态与观察窗口