前端性能数据、错误信息上报
前言
我们做前端监控系统时,当我们通过各种各样的手段进行埋点统计、错误收集等等,终于,数据有了,那么我们怎么上传呢?
单独域名上报
一般像这些数据上报使用的域名都会和业务域名分开,或者说会单独使用一台服务器部署运行。
- 从架构角度看,其实一般公司都会将业务和这些数据分开,比如有一个运营平台,数据平台什么的,比如你有很多个应用,你可以有一个数据中心统一收集这些数据。如果将这些和业务绑在一起,自然就变得很繁重了。
- 从浏览器的角度上看,很多浏览器对同一域名的请求量有并发限制,单独域名能充分利用这些并发设置。
上报的时机
实时上报
适用于数据上报并发小的情况,实时性要求高
- 页面加载完成时:这是获取和上报页面加载性能数据的一个常见时机。例如,可以在 window 的 load 事件中获取页面加载所需的时间,然后上报。
- 用户交互时:如果你想了解用户在使用网站或应用时的性能体验,可以在用户的各种交互(如点击按钮、滚动页面等)后获取和上报相关的性能数据。
- 错误发生时:当前端代码运行出错时,可以立即获取错误信息并上报,以便尽快发现并修复问题。
定时上报
适用于数据上报并发量大的情况,如一个页面中,需要上报很多条数据,可合并上报,当然要考虑后端服务是否支持合并。
页面刷新和重新刷新
这里主要讨论单页面应用,如果是非单页面应用,可以通过页面关闭时上报。
hash
可以直接监听 hashchange
|
history
history 模式主要通过 history.pushState 和 history.replaceState 方法,但浏览器不提供监听事件,那么我们可以手动添加,如下
|
页面 Tab 显示状态改变
通过监听 visibilitychange 事件,
|
页面关闭
通过 unload 事件
|
但需注意,如果使用 XHR,往往需要用同步代码,即阻塞当前页面卸载,可能会带来一些用户体验问题,因此推荐使用navigator.sendBeacon, 异步,不会被浏览器的关闭操作打断
移动端浏览器不可靠
在许多情况下(尤其是移动设备)浏览器不会产生 unload
、beforeunload
或 pagehide
事件。下面列出了一种不触发上述事件的情况:
- 用户加载了网页并与其交互。
- 完成浏览后,用户切换到了其他应用程序,而不是关闭选项卡。
- 随后,用户通过手机的应用管理器关闭了浏览器应用。
上报的方法
gif
- 不存在跨域,浏览器对照片资源加载没有跨域限制,这对单独域名上报很好解决。
- 兼容性好,基本所有浏览器都支持 gif 加载
- 相比于 png 等,体积更小
有人会觉得,跨域的话,那我服务器设置 CORS 就好啦,第一是 CORS 兼容性没有 gif 那么好,第二 CORS 可能会带来一些安全性问题,第三如果你有很多个应用公用同一个数据上报服务的话,CORS 配置维护麻烦
浏览器 URL 最大长度限制
使用 gif 上报需要考虑一个 url 长度问题,
浏览器 URL 最大长度限制参考:
浏览器 | 最大长度(字符数) |
---|---|
Internet Explorer | 2048 |
Edge | 4035 |
Firefox | 65536 |
Chrome | 8182 |
Safari | 80000 |
Opera | 190000 |
tip:
- URL 上存在中文字符会被浏览器编码,需根据浏览器编码类型将中文转换,因此,不能将中文字符长度作为 1
xhr
传统的接口上报
navigator.sendBeacon
上述的所有方法都会迫使用户代理延迟卸载文档,并使得下一个导航出现的更晚。或者处理不好会丢失这个数据上报请求,下一个页面对于这种较差的载入表现无能为力。
这就是 sendBeacon()
方法存在的意义。使用 sendBeacon()
方法会使用户代理在有机会时异步地向服务器发送数据,同时不会延迟页面的卸载或影响下一导航的载入性能,这意味着:
- 数据发送是可靠的。
- 数据异步传输。
- 不影响下一导航的载入。
数据是通过 HTTP POST 请求发送的。
结合三种上报方式
- 如果长度小于 2048,使用 gif
- 如果大于 2048,并且浏览器支持 sendBeacon,使用 sendBeacon
- 使用 XHR
|
上传优化
上报采集率
如果网页访问量很大,那么因为一个错误上报的信息可能会很多,这时候可通过设置采集率,避免全部上报。
|
识别流量高峰和低谷时期
我们可以通过一些手段识别当前是流量高峰还是低谷,动态设置上报采样率
短时间滤重
如果用户短时间内一直触发同一个错误,可考虑进行短时间滤重
监控报警
当我们监听到错误数据时,应该进行报警,如短信、群机器人等等。当然,要考虑是否会短时间内同时大量上报,可通过设置一些阀值,如 1 分钟最多报警 10 次,或者说错误达到了一定规模触发一次报警等类似
参考
侯策—《前端开发核心知识进阶》