@evertro/monitor-web
v1.1.1
Published
Evertro Monitor H5/PC 浏览器平台采集插件
Downloads
629
Readme
@evertro/monitor-web
Evertro Monitor H5/PC 浏览器平台采集插件集
概述
本包提供 H5 和 PC Web 环境下的全部采集插件,利用浏览器标准 API(window.addEventListener('error')、PerformanceObserver、IntersectionObserver、fetch/XMLHttpRequest 等)实现错误捕获、性能采集、操作链路和白屏检测。
与 @evertro/monitor-miniapp 平行,两者 API 设计对齐但底层实现完全不同。
安装
pnpm add @evertro/monitor-web插件清单
| 插件 | 类名 | 采集内容 |
|------|------|---------|
| 错误捕获 | WebErrorPlugin | JS 错误、Promise 拒绝、资源加载错误 |
| 操作链路 | WebBreadcrumbPlugin | 路由变化、点击、输入 |
| 性能采集 | WebPerformancePlugin | FCP、LCP、FP、长任务 |
| 网络监控 | WebNetworkPlugin | fetch / XMLHttpRequest 拦截 |
| 白屏检测 | WebWhiteScreenPlugin | elementsFromPoint 采样 / FCP 超时 |
插件详解
errorPlugin.ts — 错误捕获插件
采集方式:
| 错误类型 | 监听方式 | EventId |
|---------|---------|---------|
| JS 运行时错误 | window.addEventListener('error', ..., true) | E100000015 |
| 未捕获 Promise 拒绝 | window.addEventListener('unhandledrejection') | E100000023 |
| 资源加载错误 | window.addEventListener('error', ...) 捕获阶段筛选 | E100000024 |
区分 JS 错误和资源错误的方式:
window.addEventListener('error', (e) => {
if (e.target && (e.target instanceof HTMLImageElement
|| e.target instanceof HTMLScriptElement
|| e.target instanceof HTMLLinkElement)) {
// 资源加载错误
report({ type: 'resource_error', ... });
} else {
// JS 运行时错误
report({ type: 'js_error', ... });
}
}, true); // 捕获阶段,才能拦截资源错误breadcrumbPlugin.ts — 操作链路插件
采集方式:
| 链路类型 | 监听方式 |
|---------|---------|
| 路由变化 | window.addEventListener('popstate') + History API 劫持 |
| 点击操作 | document.addEventListener('click', ..., true) |
| 输入操作 | document.addEventListener('input', ..., true) |
| 前后台切换 | document.addEventListener('visibilitychange') |
History API 劫持:
// 劫持 pushState 和 replaceState
const originalPush = history.pushState;
history.pushState = function(...args) {
addBreadcrumb({ type: 'navigation', category: 'pushState', ... });
return originalPush.apply(this, args);
};点击操作记录:
{
type: 'click',
category: 'ui.click',
message: 'button.submit-btn "提交订单"', // 标签名.类名 "文本"
data: { tagName: 'BUTTON', className: 'submit-btn', id: 'submitOrder' },
level: 'info',
}performancePlugin.ts — 性能采集插件
基于 PerformanceObserver API 采集浏览器核心性能指标。
采集指标:
| 指标 | 说明 | 观察者类型 | EventId |
|------|------|-----------|---------|
| FP | First Paint 首次绘制 | paint | E100000021 |
| FCP | First Contentful Paint 首次内容绘制 | paint | E100000021 |
| LCP | Largest Contentful Paint 最大内容绘制 | largest-contentful-paint | E100000021 |
| Long Task | 超过 50ms 的长任务 | longtask | E100000021 |
采集方式:
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name === 'first-contentful-paint') {
report({ type: 'fcp', duration: entry.startTime, ... });
}
}
});
observer.observe({ type: 'paint', buffered: true });降级策略: 低版本浏览器不支持 PerformanceObserver 时,从 performance.getEntriesByType('paint') 兜底获取。
networkPlugin.ts — 网络监控插件
同时劫持 fetch 和 XMLHttpRequest。
fetch 劫持:
const originalFetch = window.fetch;
window.fetch = function(url, options) {
const startTime = Date.now();
return originalFetch.call(this, url, options)
.then(response => {
// 记录 breadcrumb + 检查状态码
return response;
})
.catch(error => {
// 网络错误上报
throw error;
});
};XHR 劫持:
const originalOpen = XMLHttpRequest.prototype.open;
const originalSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url) {
this._evertro_method = method;
this._evertro_url = url;
return originalOpen.apply(this, arguments);
};
XMLHttpRequest.prototype.send = function(body) {
// 记录开始时间、包装 onreadystatechange
return originalSend.apply(this, arguments);
};防自我监控: 检查 XHR 实例上的 _evertro_skip 属性,SDK 自己的上报请求会被跳过。
whiteScreenPlugin.ts — 白屏检测插件
检测方式:
| 方式 | API | 优先级 |
|------|-----|--------|
| elementsFromPoint | document.elementsFromPoint(x, y) | 首选 |
| FCP 超时 | 等待 FCP 超过阈值 | 降级 |
elementsFromPoint 检测原理:
┌─────────────────────┐
│ │
│ ● ● ● │ 在页面上取 N 个采样点
│ │
│ ● ● ● │ 调用 elementsFromPoint(x, y)
│ │
│ ● ● ● │ 如果返回元素只有 html/body → 该点为空
│ │
└─────────────────────┘
如果 empty/total > 阈值 → 判定白屏依赖关系
@evertro/monitor-types
@evertro/monitor-core → @evertro/monitor-web导出一览
export { WebErrorPlugin } from './errorPlugin';
export { WebBreadcrumbPlugin } from './breadcrumbPlugin';
export { WebPerformancePlugin } from './performancePlugin';
export { WebNetworkPlugin } from './networkPlugin';
export { WebWhiteScreenPlugin } from './whiteScreenPlugin';