Files

88 lines
3.7 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: frontend.fe-testing-perf.scenario.perf-regression
title: 性能治理:真实用户监控、定位慢页面、CI 性能预算和测试防回归
type: scenario
domain: frontend
stack: [fe-testing-perf, cicd]
tags: [性能监控, RUM, Lighthouse CI, 性能预算, 回归测试, INP]
level: intermediate
prerequisites: [frontend.fe-testing-perf.web-vitals, frontend.fe-testing-perf.testing]
est_hours: 2.5
related: [frontend.fe-testing-perf.interview, frontend.webpack.scenario.build-speed]
week: [7]
---
# 性能治理:真实用户监控、定位慢页面、CI 性能预算和测试防回归
## 业务背景与问题
SaaS 客服工作台(Vue / React 单页应用):客户投诉“越用越卡”,坐席在工单列表和 AI 回复面板之间切换时明显卡顿;每次大促前临时优化,之后又退化;没人说得清哪个页面、哪类设备慢。
## 约束
- 不能大规模重写。
- 坐席电脑配置参差不齐。
- 需要用数据向业务方说明优化效果。
## 方案设计
1. **可观测**:上线 RUM 采集 LCP / INP / CLS + 页面路径 + 版本号 + 设备信息;按页面和版本看 75 分位;同时采集长任务(Long Animation Frames / Long Tasks API,以 MDN 为准)。
2. **定位**:从 INP 最差的页面入手,在性能面板录制,找到长任务的调用栈。常见发现:
- 工单列表一次渲染上千行 → 虚拟列表;
- AI 回复每个 token 重新渲染整个面板 → 批量合并更新 + 局部渲染;
- 全局状态变化导致整页重新渲染 → 拆分状态、记忆化。
3. **防退化**:
- CI 中对关键页面跑 Lighthouse(实验室数据)设置预算,超出则失败;
- 产物体积预算;
- 对“竞态、防抖、批量更新”等逻辑写单元 / 组件测试;
- 每个版本对比 RUM 指标,退化告警。
4. **汇报**:用优化前后同类设备的 75 分位对比说明效果。
## 关键代码
批量合并流式 token,降低渲染频率:
```ts
export function createBatcher(flush: (text: string) => void, intervalMs = 50) {
let buffer = "";
let timer: ReturnType<typeof setTimeout> | null = null;
return {
push(token: string) {
buffer += token;
timer ??= setTimeout(() => { // 一个时间窗口内的 token 合并成一次渲染
flush(buffer);
buffer = "";
timer = null;
}, intervalMs);
},
end() {
if (timer) clearTimeout(timer);
if (buffer) flush(buffer);
buffer = "";
timer = null;
},
};
}
```
防抖与竞态的组件测试:[examples/search-box](../examples/search-box/)。
## 取舍
| 选择 | 优点 | 缺点 |
| --- | --- | --- |
| **RUM + 实验室预算(本方案)** | 既知道真实情况,又能在合并前拦截退化 | 需要搭建采集和看板 |
| 只用 Lighthouse | 简单 | 与真实用户体验有差距,尤其是 INP |
| 使用第三方性能监控平台 | 开箱即用 | 成本、数据合规(客服数据不能随便上报) |
## 易错点
- 上报数据中带了客户的敏感信息(URL 参数中的手机号、工单内容)。
- 只看平均值。
- 批量渲染的定时器在组件卸载时没有清理。
- 优化了实验室分数,真实 INP 没变化:交互卡顿往往在登录后的复杂页面,Lighthouse 默认测不到。
## 面试怎么讲
> “先建立度量:线上采集 Web Vitals 按页面和版本看 75 分位,发现工作台的 INP 最差。用性能面板定位到两个长任务:工单列表全量渲染和 AI 回复逐 token 重渲染,分别改成虚拟列表和 50ms 批量更新。然后在 CI 加 Lighthouse 和体积预算、给关键交互逻辑写测试防止退化。效果用优化前后同类设备的 75 分位对比(数据以实测为准)。”