场景题: “现有的业务在裸奔,老板和数据分析团队需要掌握所有新上线功能的:页面访问量(PV / UV)、用户的转化漏斗、以及 JS 代码的崩溃报错情况以便于紧急修复。 请你设计并讲解一套涵盖前端性能、事件行为上报、异常捕获的打点(Tracking)与监控机制方案。”
大型互联网公司的业务前端无一例外长着无数的“眼睛和传感器”。答好这道题,必须将问题域清晰划分为三大模块:数据捕获、上送机制、架构解耦。
通常我们要捕捉上报的数据有三大类:
onClick 事件内部最末尾,写死如 Tracker.send('btn_submit')。控制最准,但代码侵入极强,极其容易在日后由于交接变成没人敢碰的烂代码。data-* 属性的标记。如 <button data-tracking-action="login">。依靠一个全局代理委托监听全局 document 冒泡上来的点击事件,通过辨认携带了该特定标志位而统一集中上报。极大地净化了业务逻辑本身。window.onerror 和 window.addEventListener('error') 全天候监控老式 JS 致命错误,或者图片获取死链。window.addEventListener('unhandledrejection') 擒拿由于未写 catch 逃窜的 Promise 错误。app.config.errorHandler 防患于未然;React 则必然利用 Error Boundary(错误边界实例) 包裹全系重要组件在生命周期 componentDidCatch 时发起异常大字报紧急呼救。数据抓取好了,我们怎么把这些监控数据发给后端?如果只是傻傻地用 Axios 或 Fetch POST 接口,你会在面试中面临以下追问和灵魂打击:
OPTIONS 请求和死角拦截。beforeunload)记录用户最后停留秒数做上报。如果你使用 Fetch 或 AJAX,请求必定随着页面关闭的主进程消亡而被无情腰斩杀死!由于连接断开,服务器根本啥也收不到!因此前端上报埋点有一套隐秘在阳光下的专业方法论。
我们极度常见地利用构造极小图片实体 Image 来挂载信息发送:
优势:完美规避了浏览器的 AJAX 跨域检查(图片加载无所畏惧),且不污染当前页面任何逻辑;且 1x1 的空 GIF 图片是被公认为网络负载响应体积最小的黑科技方案。
这是 W3C 官方看见了“我们前段人强用 1X1 像素图片钻空子实在太苦逼了”后诞生的专门的打点上报神龟:sendBeacon。
它的绝对优势(面试王牌得分点):
如果你系统 PV 破千万量级,难道一次疯狂的滑动和页面打开我们要真实发出 50 次 sendBeacon 把自己的日志接口也打垮吗?
高阶架构需要:防抖/削峰合并。
前端在全局维持着一个微小且带有阈限的 Data 池子(Array)。所有事件探针搜集到情报不要当即去发网络请求,而是偷偷塞进 pool.push() 中。
随后开启 requestIdleCallback 钩子或者设定阈值达到 10 项时以及卸载监听触达时,集中打包这些 Array ,统一整合成一个大体积的 JSON 请求使用一次 Beacon 发射给后方。极大降低信令信道浪费导致的建立 TCP 之苦。