各位前端同行,咱们今天聊聊前端监控。别告诉我你还在等用户截图告诉你应用崩了,那感觉就像等邻居来告诉你你家着火了——能知道,但已经晚了。
为什么你需要前端监控
最近看到一个项目,生产环境崩溃了 3 小时,开发团队却一无所知。我就想问:你是在做应用还是在做猜谜游戏?
反面教材
// 反面教材:没有监控
// components/Checkout.jsx
export default function Checkout() {
const [loading, setLoading] = useState(false);
const handleSubmit = async () => {
setLoading(true);
try {
await api.checkout();
// 成功处理
} catch (error) {
// 只在控制台打印错误
console.error('Checkout failed:', error);
// 显示错误信息
setError('支付失败');
} finally {
setLoading(false);
}
};
return (
<button onClick={handleSubmit} disabled={loading}>
{loading ? '支付中...' : '支付'}
</button>
);
}
// 错误只在控制台,开发团队看不到
// 用户遇到问题只能截图反馈
毒舌点评:这代码,错误只在控制台,你是在写应用还是在玩捉迷藏?
前端监控的正确姿势
1. 错误监控
// 正确姿势:Sentry 错误监控
// src/utils/errorMonitoring.js
import * as Sentry from '@sentry/react';
export function initSentry() {
Sentry.init({
dsn: 'YOUR_SENTRY_DSN',
integrations: [
new Sentry.BrowserTracing(),
new Sentry.Replay()
],
tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1
});
}
export function captureError(error) {
Sentry.captureException(error);
}
export function captureMessage(message) {
Sentry.captureMessage(message);
}
// 使用
// components/Checkout.jsx
import { captureError } from '../utils/errorMonitoring';
const handleSubmit = async () => {
try {
await api.checkout();
} catch (error) {
captureError(error);
setError('支付失败');
}
};
2. 性能监控
// 正确姿势:性能监控
// src/utils/performanceMonitoring.js
import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
export function initPerformanceMonitoring() {
getCLS(console.log);
getFID(console.log);
getFCP(console.log);
getLCP(console.log);
getTTFB(console.log);
}
// 集成到 Sentry
import * as Sentry from '@sentry/react';
export function sendToSentry({ name, delta, id }) {
Sentry.metrics.distribution(name, delta, {
tags: { id }
});
}
getCLS(sendToSentry);
getFID(sendToSentry);
getLCP(sendToSentry);
3. 用户行为监控
代码高亮:
// 正确姿势:用户行为监控
// src/utils/userMonitoring.js
import * as Sentry from '@sentry/react';
export function trackEvent(eventName, data) {
Sentry.captureEvent({
message: eventName,
extra: data
});
}
export function trackClick(element, eventName) {
element.addEventListener('click', () => {
trackEvent(eventName, {
timestamp: new Date().toISOString()
});
});
}
// 使用
// components/Button.jsx
import { trackClick } from '../utils/userMonitoring';
export default function Button({ onClick, children }) {
const buttonRef = useRef(null);
useEffect(() => {
if (buttonRef.current) {
trackClick(buttonRef.current, 'button_clicked');
}
}, []);
return (
<button ref={buttonRef} onClick={onClick}>
{children}
</button>
);
}
毒舌点评:这才叫现代前端,实时监控,问题早发现早解决。
阅读原文
该文章在 2026/4/8 15:15:40 编辑过