浪白的博客の小站
首页项目归档照片墙音乐灵境说说杂谈友链关于
封面

工具链的耐心是有限的

2026-08-05 22:00:00
✨ 心情:吐槽
# 随笔
# 工具
# 效率

最近在优化项目的构建流程,顺手算了一下时间账,有点触动。

先算个数

改造前的流程:

步骤 耗时
装依赖(有缓存) 20s
静态检查 35s
单元测试 50s
构建产物 40s
部署到测试环境 25s
合计 170s

接近三分钟。这还不算排队等 CI runner 的时间。

假设我一天提交 15 次,那是 42 分钟。加上偶尔失败重跑,一天一小时。

一天一小时在等构建。 而且这个等待是打断式的——你不能安心去做别的,因为几分钟后就要回来看结果。

等待为什么比看起来更贵

如果一天有一小时纯粹的空闲,那还好。但实际不是:

一、上下文切换的成本。

我在等构建的时候,会去开个浏览器、看个消息、读篇文章。等构建好了,回到代码上需要重新建立上下文。这个成本可能比构建本身还大。

二、它改变了我提交的方式。

因为构建慢,我会攒着改动一起提交。"等这几个功能都做完再跑一次 CI"。结果一次提交五百行,出问题的时候很难定位。

三、它让人倾向于跳过检查。

本地跑测试要 50 秒,急着验证一个想法的时候就会想"这次先跳过,CI 会跑"。然后 CI 也跳过了(或者没人看结果)。

我做的优化

一、并行化。

静态检查和单元测试没有依赖关系,可以同时跑:

jobs:
  static:
    steps: [ ... ]
  test:
    steps: [ ... ]

170s → 大概 110s(取最长的那条链路)。

二、缓存依赖。

这个是投入产出比最高的。依赖不变的时候直接命中缓存,20s → 3s。

缓存 key 要用 lock 文件的哈希:

key: deps-${{ hashFiles('composer.lock') }}

不要用分支名做 key,那样每个分支第一次都要重装。

三、测试分片。

测试拆成 4 份并行跑:

# 用 paratest 或者自己按测试类哈希分片
vendor/bin/paratest --processes=4

50s → 15s。

四、只跑受影响的测试。

这个需要工具支持(比如 phpunit --filter 配合 git diff 分析),准确率不完美,容易漏测。我用在本地开发的 watch 模式里,CI 上还是跑全量。

五、部署改成增量。

原来是每次全量打包上传。改成只传变化的文件,25s → 8s。

优化后:

步骤 耗时
装依赖(缓存命中) 3s
检查 + 测试(并行) 20s
构建 40s
部署 8s
合计 71s

从 170s 到 71s。一天省下大概 25 分钟。

但真正的问题可能不是速度

优化完之后我在想:就算变成 30 秒,那一天还是 15 次提交,其中可能有一半是"改个错别字"或者"调一下日志"。

频繁的小提交本身可能才是问题。

不过这个不好一概而论。快速反馈循环对某些工作方式是有益的(比如边写边验证),只是不该每次都触发完整流程。

我现在的做法是分两层:

  • 快速检查(保存时自动跑):语法、代码风格、单文件测试。5 秒内。
  • 完整流程(提交时跑):全量测试、构建、部署。接受它慢一点。

关键是让开发者能自己选择。不是所有改动都需要完整验证。

一些不太明显的成本

一、本地环境的启动时间。

如果新同事 clone 下来要两小时才能跑起来,那这个项目在有意识地排斥贡献。我们目标是 10 分钟以内(下载依赖不算)。

现在用 docker compose up 一条命令起来,加上一份初始化脚本填充测试数据。

二、报错信息的质量。

静态检查报一个错,如果信息是 Error in line 42,我得自己去找问题。如果能说清楚"这个参数类型不匹配,期望 int 得到 string",我一眼就知道怎么改。

花时间定制检查工具的输出格式,收益比想象中大。

三、日志的查找难度。

线上出问题,从告警到定位到具体请求,如果需要二十分钟翻日志,那比代码 bug 本身更耗时。

我们后来统一了 trace id,一个请求跨几个服务都能串起来。这个改造花了两天,之后每次排查省的时间累积起来很可观。

关于"等构建的时候干什么"

我之前的做法是切去干别的。后来发现效果不好,因为:

  • 构建只有两分钟,干不了需要深度思考的事
  • 被打断之后回到原来的思路要时间

现在我的做法是:

  • 构建期间只看轻量的东西:review 一下 diff、更新一下任务状态、回个消息
  • 需要深度思考的事情,攒到构建跑完再做

或者更好:把两个不相关的任务交替做。A 的构建在跑,我去写 B 的设计文档。

一点反思

我以前觉得"工具链慢"是个客观限制,忍受就好。

现在觉得它是个可以也应该被优化的东西,因为:

  1. 它每天都发生
  2. 它的成本是隐性的(不会有人为"等构建"建个工单)
  3. 它影响的是所有人的效率

我见过一些团队对"构建慢"的态度是"就那样吧,反正能跑"。但如果你算一下一年在这个上面花掉多少人天,可能会想改改。

最后

优化完之后最大的感受不是"快了 2.4 倍",而是我提交的时候不那么犹豫了。

以前改个小东西会想"值不值得跑一次 CI",现在随手就跑了。这个心理变化带来的是更好的习惯——小步提交、频繁验证。

工具的速度影响的不只是时间,还有工作方式和心态。

avatar

浪白

邪恶的浪白

2026年8月

一
二
三
四
五
六
日
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

Recent Records

写给刚开始写代码的自己

2026-08-28 21:45:00

"够用就好"这四个字,我花了很久才懂

2026-07-15 23:10:00

重读自己五年前写的代码

2026-05-30 21:25:00