phase 5 part 2: vite 8, webpack 5, fe-testing-perf topics with verified examples

This commit is contained in:
Shikui Wang committed 2026-10-23 16:29:27 +08:00
1 parent 7b5cae7d24
commit 9eeb10aede
38 files changed
+1823 -37

No files matched your search

@@ -0,0 +1,87 @@
---
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 分位对比(数据以实测为准)。”