背景
我们是一个 B 端 SaaS 前端(React 18 + Vite 5,约 30 个中后台页面),核心看板页线上 RUM LCP P75 基线在 1.9~2.2s(取决于用户网络),Lighthouse CI 在 CI 环境(4G 模拟、headless Chrome)里跑出来 LCP 分数在 70~85 之间波动。
去年我们推了一轮"性能预算进 CI",门禁规则是:
- Lighthouse LCP 分数 < 70 → block 合并
- JS bundle 增量(gzip 后)> 50KB → block 合并
- CLS > 0.1 → block 合并
现象(卡点)
跑了 3 个月后,团队对这个门禁产生了明显的"信任裂缝":
- 过松:上个月一个 PR 把 vendor chunk 从 412KB 涨到 487KB(+75KB),Lighthouse LCP 分数从 78 掉到 72,没触发 block(阈值 70),但上线后线上 RUM LCP P75 从 2.0s 涨到 2.4s——用户可感知劣化,CI 却全绿。
- 过紧:另一个 PR 只是多引了一个 12KB 的日期选择器组件,Lighthouse LCP 分数从 82 掉到 76(分数波动 ±4 很常见),触发了 block,但 bundle 增量只有 12KB、线上 LCP 几乎没动——被误伤,开发同学开始绕过门禁。
- 校准缺失:我翻了 6 个月的 CI 日志和 RUM 数据,没有找到一组稳定的"Lighthouse 分数 → 线上 LCP P75"映射关系。同一个分数 75,对应的线上 P75 可能是 1.8s 也可能是 2.5s(取决于用户网络分布、CDN 命中率、浏览器版本)。
已尝试的排查与结果
- 直接拿 Lighthouse 分数当门禁:如上,分数波动大,阈值不好定。
- 改用 bundle 体积做硬卡:更稳定,但"体积 ≠ 性能"——一次 80KB 的增量可能全是 tree-shaking 没砍掉的 tree,对 LCP 毫无影响;另一次 20KB 的增量恰好命中关键渲染路径,LCP 涨 300ms。
- 加 TBT(Total Blocking Time)做辅助指标:Lighthouse CI 里 TBT 波动比 LCP 更大(±200ms 很常见),门禁更难定。
- 用 WebPageTest 跑真实设备:更准,但 CI 里跑一轮要 5~8 分钟,开发耐心被磨光,最后没人等。
期望得到的答案形态
- 校准方法:有没有人建过"Lighthouse CI 分数/指标 → 线上 RUM P75"的映射表或回归模型?具体怎么做(采样多少版本、用什么统计方法、多久校准一次)?
- 阈值设定:在映射关系建立后,门禁阈值怎么从"线上 SLO 反推"而不是"拍脑袋定一个分数"?容错带(±多少)怎么定?
- 多指标组合:LCP 分数 + bundle 体积 + TBT + CLS 这 4 个指标,哪些该硬卡(block)、哪些该软卡(warn + 人工 review)?有没有可复用的组合方案?
- CI 环境 vs 线上的 gap 怎么量化:4G 模拟、headless Chrome、无真实用户数据——这些"失真源"各自贡献多少偏差?有没有人拆过?
我引用了 #1431(性能预算进 CI 的讨论)和 #918(vendor chunk 体积基线与 CI 门禁)作为背景参考,但这两个都没涉及"CI 分数 → 线上 P75"的校准问题。