Q12 · 监控与调试
如何设计一个前端监控体系?数据采集和清洗怎么做?
⚡ 速记答案(30 秒)
- 采集:注入 SDK,利用
Performance API、Resource Timing、paint/layout-shift等拿指标 - 统一封装上报接口(批量 + 采样 + 限流);采集用户环境(UA、网络、版本)和业务上下文
- 清洗:去重、过滤异常值(如离线重试、测试环境)
- 统一时间/区间、维度(地区、版本、设备)
- 生成聚合指标:P50/P75/P90、错误率、慢页面 TopN
🎮 交互 Demo - 性能指标采集
当前页面性能指标
打开浏览器 DevTools → Performance 面板查看详细指标
💡 提示:使用 web-vitals 库可以方便地获取 LCP、FID、CLS 等核心指标。
📖 详细讲解
监控体系架构
用户浏览器 → SDK 采集 → 上报网关 → 数据处理 → 存储 → 可视化/告警采集内容
1. 性能指标
• Core Web Vitals (LCP, FID, CLS)
• 资源加载时间
• 接口响应时间
2. 错误信息
• JS 运行时错误
• 资源加载错误
• 接口错误
3. 用户行为
• PV/UV
• 点击、滚动
• 页面停留时间
上报策略
• 批量上报:合并多条数据一起上报
• 采样上报:高流量场景按比例采样
• 空闲上报:使用 requestIdleCallback
数据处理
• 去重:相同错误合并
• 聚合:计算分位数 P50/P75/P90
• 维度拆分:按地区、设备、版本分析
💻 代码示例
简易性能监控 SDK
class PerformanceMonitor {
private queue: any[] = [];
private timer: number | null = null;
init() {
this.observeWebVitals();
this.observeErrors();
this.observeResources();
}
// 收集 Web Vitals
private observeWebVitals() {
import('web-vitals').then(({ onLCP, onFID, onCLS }) => {
onLCP((metric) => this.report('LCP', metric.value));
onFID((metric) => this.report('FID', metric.value));
onCLS((metric) => this.report('CLS', metric.value));
});
}
// 收集错误
private observeErrors() {
window.addEventListener('error', (e) => {
this.report('js_error', {
message: e.message,
filename: e.filename,
lineno: e.lineno,
});
});
}
// 批量上报
private report(type: string, data: any) {
this.queue.push({
type,
data,
timestamp: Date.now(),
url: location.href,
userAgent: navigator.userAgent,
});
this.scheduleFlush();
}
private scheduleFlush() {
if (this.timer) return;
this.timer = window.setTimeout(() => {
this.flush();
this.timer = null;
}, 5000); // 5秒批量上报
}
private flush() {
if (this.queue.length === 0) return;
const data = this.queue.splice(0);
navigator.sendBeacon('/api/monitor', JSON.stringify(data));
}
}面试技巧:回答性能问题时,先说指标和标准,再讲优化手段,最后结合实际项目经验。