你想做的是一個 前端監控系統(Frontend Monitoring / RUM, Real User Monitoring),主要包括:
異常監控(JS 報錯、資源加載錯誤、Promise 未捕獲異常)
性能監控(白屏時間、首屏時間、頁面加載時間、TTFB、FCP、LCP、CLS 等指標)
行為監控(PV/UV、路由變化、用戶操作)
上報機制(采集到的數據怎么上報到監控服務)
可視化與報警(監控后臺分析、日志存儲、異常告警)
下面我給你出一份 詳細方案(從埋點到數據上報再到后端處理):
一、整體架構
前端 SDK(埋點腳本)
集成到業務項目中(JS/TS SDK)。
負責采集:
JS 錯誤(
window.onerror
,window.addEventListener('error')
,unhandledrejection
)性能指標(
Performance API
、PerformanceObserver
)用戶行為(
click
,hashchange
,popstate
等事件)
負責數據上報(
sendBeacon
/fetch
/img.src
)。
數據上報服務(Node.js/Go/Python)
接收 SDK 上報的日志。
存儲到數據庫(如 Elasticsearch、ClickHouse、MongoDB)。
提供查詢/分析 API。
可視化與報警
Web 管理后臺(React/Vue/Antd)展示監控指標。
Grafana/ELK/Prometheus 也可以做日志與指標可視化。
結合釘釘/企業微信/Slack 做告警。
二、前端 SDK 設計與實現
1. JS 錯誤監控
// 監聽同步運行時錯誤
window.onerror = function (msg, url, line, col, error) {report({type: 'js_error',msg,url,line,col,stack: error?.stack});
};// 監聽資源加載錯誤 (img, script, css)
window.addEventListener('error', function (e) {if (e.target && (e.target.src || e.target.href)) {report({type: 'resource_error',tagName: e.target.tagName,src: e.target.src || e.target.href});}
}, true);// 監聽 Promise 未捕獲異常
// 對 👍,window.addEventListener('unhandledrejection') 就是專門用來捕獲 未被捕獲的 Promise 異常 的。
// 在 JavaScript 中,如果你寫了一個 Promise,但是沒有在 鏈路的最后 .catch() 處理錯誤,瀏覽器就會觸發一個 unhandledrejection 事件。window.addEventListener('unhandledrejection', function (e) {report({type: 'unhandledrejection',reason: e.reason});
});
2. 性能監控(Performance API)
白屏時間:從
navigationStart
到 首次 DOM 繪制(FP/FCP)。首屏時間:業務可定義,如首屏主要內容渲染完成。可通過
MutationObserver
或在業務點埋點。頁面加載時間:
loadEventEnd - navigationStart
。核心 Web Vitals:
FCP
(First Contentful Paint)LCP
(Largest Contentful Paint)FID
(First Input Delay)CLS
(Cumulative Layout Shift)
示例:
function getPerformance() {const timing = performance.timing;const paint = performance.getEntriesByType('paint');const nav = timing.navigationStart;return {whiteScreen: paint.find(e => e.name === 'first-paint')?.startTime || 0,fcp: paint.find(e => e.name === 'first-contentful-paint')?.startTime || 0,load: timing.loadEventEnd - nav,domReady: timing.domContentLoadedEventEnd - nav,ttfb: timing.responseStart - nav};
}window.addEventListener('load', () => {setTimeout(() => {report({type: 'performance',data: getPerformance()});}, 3000);
});
3. 用戶行為監控(可選)
路由變化監控(SPA:監聽
popstate
,hashchange
)。點擊行為監控(采集
click
元素路徑,做埋點統計)。自定義事件埋點(開發者主動上報)。
// 路由變化
window.addEventListener('hashchange', (e) => {report({type: 'route_change',from: e.oldURL,to: e.newURL});
});
4. 數據上報機制
高優先級(報錯、關鍵性能數據):
navigator.sendBeacon
(頁面卸載前保證發送成功)。低優先級:批量
fetch
上報。兜底方案:
new Image().src = 'url?...'
。// 兼容性最好,兼容老瀏覽器 + 頁面卸載時也能發請求
function report(data) {const url = 'https://monitor.xxx.com/report';const body = JSON.stringify({...data,userAgent: navigator.userAgent,url: location.href,timestamp: Date.now()});if (navigator.sendBeacon) {navigator.sendBeacon(url, body);} else {fetch(url, { method: 'POST', body, keepalive: true });}
}
三、后端服務(示例)
Node.js + Express + MongoDB/Elasticsearch/ClickHouse
接收上報:
app.post('/report', (req, res) => {const data = req.body;// 存儲日志db.collection('logs').insertOne(data);res.json({ code: 0 });
});
定時聚合分析(統計錯誤率、性能指標分布)。
四、可視化與報警
指標面板(可視化框架:ECharts/Grafana):
JS 錯誤率(隨時間趨勢)
頁面加載時間分布
用戶地區、設備分布
異常報警:
錯誤率 > 1%
頁面白屏時間 > 3s
LCP > 4s
→ 觸發告警,推送到釘釘/企業微信。
五、優化與擴展
支持 SourceMap 解析,錯誤堆棧反解到源碼位置。
支持 Session 關聯(用戶 ID、會話 ID)。
支持 前后端鏈路追蹤(結合 Trace ID,關聯后端 APM)。
支持 采樣率(例如 1% 用戶采集,降低服務器壓力)。
📌 總結:
實現一個前端監控系統主要分 采集(前端 SDK) → 上報(sendBeacon/fetch) → 存儲(DB/ES) → 分析與報警(Dashboard+告警系統) 四個環節。
你可以先做一個 輕量級 SDK + Node 后端 + Grafana 可視化 的 MVP 版本,然后逐步擴展。