告别“裸奔”:全方位构建前端监控与容灾体系
本文深入探讨了前端监控的重要性,从核心性能指标、全链路错误捕获、高效数据上报策略到自动化告警与容灾保障,全方位解析如何构建一套稳健的前端监控体系,让线上问题无处遁形。
一、为什么需要前端监控
线上问题发现严重滞后(用户投诉才知道出了 bug)
性能瓶颈缺乏量化数据支撑
用户行为数据驱动产品迭代
容灾机制保障核心链路可用性
一句话概括:没有监控的系统等于裸奔——出了问题不知道、出了多久不清楚、影响多少用户没概念。
二、监控指标体系
分类 | 核心指标 | 含义 |
|---|---|---|
性能 | LCP / FCP / INP / CLS / TTFB | Core Web Vitals + 首字节时间 |
错误 | JS 异常率 / API 错误率 / 资源加载失败率 | 稳定性核心指标 |
业务 | PV/UV / 停留时间 / 跳出率 / 转化率 | 用户行为与业务效果 |
资源 | 首屏包大小 / 资源加载耗时 / 缓存命中率 | 资源加载效率 |
三、错误采集
全链路错误捕获
// 1. 同步 JS 错误
window.onerror = function(msg, url, line, col, error) {
report({ type: 'js_error', msg, url, line, col, stack: error?.stack });
};
// 2. 未处理的 Promise 异常
window.addEventListener('unhandledrejection', (event) => {
report({ type: 'promise_error', reason: event.reason?.message || String(event.reason) });
});
// 3. 资源加载失败(img / script / css)— 必须用捕获阶段
window.addEventListener('error', (event) => {
if (event.target !== window) {
report({ type: 'resource_error', tag: event.target.tagName, src: event.target.src || event.target.href });
}
}, true);
// 4. React 组件错误
class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
report({ type: 'react_error', error: error.message, componentStack: errorInfo.componentStack });
}
render() { return this.props.children; }
}
// 5. API 错误:封装 axios 拦截器
axios.interceptors.response.use(null, (error) => {
report({ type: 'api_error', url: error.config?.url, status: error.response?.status });
return Promise.reject(error);
});1. Source Map 还原
线上代码是压缩的,需要上传 Source Map 到监控平台还原源码位置
2. 错误聚合
按 message + stack 指纹去重,避免重复告警
四、性能采集
Core Web Vitals 采集
import { onLCP, onFID, onCLS, onINP, onTTFB } from 'web-vitals';
onLCP((metric) => report({ name: 'LCP', value: metric.value }));
onCLS((metric) => report({ name: 'CLS', value: metric.value }));
onINP((metric) => report({ name: 'INP', value: metric.value }));
onTTFB((metric) => report({ name: 'TTFB', value: metric.value }));
// 自定义性能指标
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name === 'first-contentful-paint') {
report({ name: 'FCP', value: entry.startTime });
}
}
});
observer.observe({ type: 'paint', buffered: true });
// 慢资源告警
const resObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 3000) {
report({ name: 'slow_resource', url: entry.name, duration: entry.duration });
}
}
});
resObserver.observe({ type: 'resource', buffered: true });Navigation Timing:页面加载各阶段耗时(DNS / TCP / TTFB / DOM 解析等)
Long Task:PerformanceObserver 监听超过 50ms 的长任务
五、数据上报
上报策略实现
const reportQueue = [];
function report(data) {
reportQueue.push({
...data,
timestamp: Date.now(),
url: location.href,
userAgent: navigator.userAgent,
});
if (reportQueue.length >= 10) flush();
}
function flush() {
if (reportQueue.length === 0) return;
const data = JSON.stringify(reportQueue.splice(0));
// sendBeacon:页面卸载时也不会丢数据
if (navigator.sendBeacon) {
navigator.sendBeacon('/api/report', data);
} else {
fetch('/api/report', { method: 'POST', body: data, keepalive: true });
}
}
setInterval(flush, 5000);
window.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'hidden') flush();
});1. 关键策略
采样策略:高流量场景按比例采样(如 10%),降低服务端压力
数据脱敏:上报前过滤敏感信息(token / 密码等)
离线暂存:弱网时存 IndexedDB,恢复后补报
六、告警与容灾
1. 告警规则
错误率突增 > 阈值 / LCP P75 > 2.5s / API 成功率 < 99%
2. 监控平台
Sentry:错误监控首选(Source Map / Issue 聚合 / Release 追踪)
Grafana + Prometheus:自建可视化看板
DataDog / New Relic:全栈 APM
3. 容灾策略
CDN 降级:主 CDN 不可用切备用
白屏兜底:ErrorBoundary + 降级 UI
开关控制:Feature Flag 快速关闭问题功能
总结
核心心法
1. 前端监控三大维度:错误 + 性能 + 业务,缺一不可
2. 错误采集要全链路覆盖:同步错误 / Promise / 资源 / 组件 / API 五个入口
3. 性能采集以 Core Web Vitals 为核心指标,PerformanceObserver 是底层 API
4. 上报策略的关键:sendBeacon 防丢失 + 批量上报 + 采样降压
5. 容灾不是"锦上添花"而是"保命手段":CDN 降级 + 白屏兜底 + Feature Flag 三件套