简历回答逐字稿:监控 SDK 性能与异常采集

关联:简历追问:监控 SDK 性能与异常采集15分钟:前端埋点与监控 SDKSDK 异常劫持会不会影响主业务的正常请求

30 秒开场

性能和异常采集这块,我的原则是先保证 SDK 不伤害主业务,再谈采得全。它会接入很多业务页面,如果覆写 fetch 或监听全局异常时把业务行为改了,那就是基础设施事故。

所以我会用 PerformanceObserver 采集 FCP、LCP、CLS 等指标,用 window.onerrorunhandledrejection、资源错误和 Fetch/XHR 代理采集异常。同时所有采集逻辑都做 try-catch、旁路队列和降级,上报失败只能丢监控,不能影响业务。

如果面试官问:Web Vitals 怎么采?

我会说核心依赖 PerformanceObserver。

FCP 来自 paint entry,LCP 来自 largest-contentful-paint entry,CLS 来自 layout-shift entry。观察时要考虑 buffered: true,否则 SDK 延迟加载时可能错过早期指标。

SPA 场景要先定义口径。浏览器原生 LCP 更偏首次页面加载,如果要看路由级体验,需要额外定义 route view 的开始时间、关键内容渲染点和自定义指标,不能简单把每次路由切换都叫 LCP。

CLS 也要注意排除用户输入后的合理布局变化,并尽量记录造成抖动的元素信息,便于排查。

如果面试官追:Fetch/XHR 劫持会不会影响业务?

我会明确说这是最需要小心的地方。

代理 fetch 时,第一原则是保留原始语义。不能修改入参引用,不能吞掉 AbortController,不能改变 Promise reject/resolve 行为。采集逻辑一定包在 try-catch 里,哪怕 SDK 自己报错,也要回到 nativeFetch.apply(this, args)

响应体也不能随便读。比如直接 response.json() 会消耗 stream,业务后面就读不到了。如果确实要读 body,只能 response.clone() 后在副本上处理,而且还要考虑大 body 的成本。

如果面试官追:Abort 算不算异常?

我会说不能一刀切。

用户切换页面、搜索框取消旧请求、组件卸载时 AbortController 主动取消,这类一般不应该当成服务端异常。它可以作为请求取消事件上报,但不应该计入接口错误率。

真正需要标红的是网络失败、超时、DNS/TLS 之类的请求失败,或者后端返回 5xx。4xx 也要区分:401/403 是鉴权,400 可能是前端参数问题,404 可能是资源不存在。指标口径要清楚,否则大盘会误导。

如果面试官追:sendBeacon 失败怎么办?

我会说正常运行时事件先进入内存队列,批量上报。页面卸载时,优先用 navigator.sendBeacon 发小体积关键事件。如果 Beacon 不可用、payload 超限或被策略阻止,可以降级到 fetchkeepalive

如果仍然失败,关键事件可以进入 IndexedDB 离线队列,网络恢复后续传。这里要有幂等 id、重试次数、过期时间和批量限流,避免恢复网络时一次性打爆服务端。

如果面试官追:SDK 自身性能怎么控制?

我会说 SDK 要默认把自己当成低优先级任务。

初始化尽量晚于关键渲染路径,非必要插件延迟加载。采集到事件后只 push 到队列,不在事件回调里做复杂计算。批量序列化和上报可以放到空闲时间或 Worker。包体也要拆插件,业务不用的能力不要强行打进去。

如果被追问效果,我不会说“肯定不影响”,我会讲验证方式:看 SDK 加载体积、初始化耗时、长任务、首屏指标差异,以及异常情况下是否能远程关闭某个插件。

收尾句

所以我做性能和异常采集时,不是尽可能多地劫持浏览器,而是在采集覆盖率和无害性之间取平衡。监控 SDK 的底线是托底,而不是成为新的故障源。