跳至主要內容

前端监控数据上报请求、图片打点和sendBeacon三种方式对比

Hew.iShare大约 5 分钟javascript技术前端监控图片打点sendBeacon

背景

最近在做前端监控项目时,遇到了关于前端数据上报方式的相关问题。故在此做一个分析和探讨,来比较和分析一下哪种上报方式时最优的,或者说,哪一种上报方式更适合自身,适合当前的业务。我认为,抛开实际使用场景谈孰优孰劣就是耍流氓。凡是都要实事求是,一切从实际出发,才能找出最优解。

实现方式

目前业界前端采集上报数据的实现方式,大致分三种。一种为接口请求方式上报,一种为图片打点方式上报,另一种为使用比较新的navigator.sendBeacon API进行上报。

接口请求

接口请求指通过Ajax/Fetch等方式,将收集到的数据通过固定的接口发送给服务端,即我们业务中通常向后端请求接口发送数据的方式。这种方式发送数据相对来说比较简单,使用post接口可以发送比较大量的数据。这种方式是异步,不会阻塞和影响页面正常渲染,但是,还是会占用一定的客户端资源,且需要特殊处理跨域限制。

图片打点

图片打点方式即通过请求一个图片,通常为1乘1px大小图片,然后将收集的数据拼接在这个图片的url后面,这样,静态资源服务器(比如nginx服务器)就能记录到请求的信息,将其存入日志。之后,便可以通过分析存入的日志,获取到所收集到的信息。这种方式可以说是一条蹊径,简单,占用资源低且天然可跨域,目前大部分前端监控上报产品都采用了类似的方式,进行数据的收集。但是,由于是get请求,对上报的数据量有一定的限制。

sendBeacon

navigator.sendBeacon是一个比较新的API,它能异步的以post方式发送数据到服务端,且不会影响页面渲染和阻塞页面,即使页面关闭,也不会影响其数据的发送,浏览器会对其进行调度,以确保其可靠性和最低影响性。并且不受跨域限制,浏览器兼容性也比较好,可以支持除IE之外的几乎所有浏览器。其采集数据方式,即可以像请求一样直接拿到上报的数据进行存储,也可以像图片打点一样,来存储日志,再做分析。

对比

根据以上我们对三种类型数据上报方式的介绍,下面对其从多个角度做一个对比,这样,我们看起来也会更直观。

方式类型/对比参数接口请求图片打点sendBeacon
资源占用大小一般post传输,相对开销较大很小较小
是否阻塞页面异步不阻塞页面,同步会阻塞页面不阻塞不阻塞
传输数据大小使用post传输量很大,无特殊限制由于使用get,传输量比较小,一般为2~8kb较小 Chrome最大64kb,长度不超过65536open in new window个字符
跨域默认不支持跨域,需要特殊配置天然支持跨域支持跨域
安全性一般由于请求的是静态资源相对安全一般
兼容性比较好;需要支持js脚本及XHR极好,可以说是任何设备浏览器比较好;除IE之外绝大多数PC和手机浏览器,包括国产的UC、QQ、Baidu等
实施难度相对简单,和开发业务类似相对复杂,需要先记录日志,再分析日志,获取数据可以简单可以复杂,取决于采取的是打点日志方式还是直接解析数据方式

结论

从上面的对比中我们可以看出,三种数据上报方式没有一种方式在任何方面都是优秀的,都有一定的优缺点。接口请求可以传输较大数据量,但是,其性能开销和跨域存在缺陷。图片打点各方面都很优秀,但是其上报数据量有大小限制。sendBeacon各方面指标也不错,但是不能兼容IE。所以,对于不同的业务目标,我们可能需要采取不同的方式去进行数据的上报。

如果采集指标数据量比较大,甚至我还要通过分析客户端渲染截图等大量数据采集的场景,此时,post接口请求应该更适合这样的场景。而对于数据采集量比较小,比如,只是采集一些客户端的pv、uv 、以及错误,或者说对兼容性要求较高等,此时采用图片打点的方式,应该是最好的选择。而还有一些场景,我们对指标的可靠性要求较高,比如,需要统计页面停留时间,浏览时长、关闭或跳转页面行为等,此时使用sendBeacon就可以保证数据可靠性,保证数据即使是跳转和关闭页面,也能正常发送收集的数据到服务端。

当然,上述三种上报数据的方式并不是孤立的,也可以根据不同场景选择多种上报方式。我们为了保证数据可靠性,可以优先使用sendBeacon方式进行上报,再不支持此API情况或者传输数据失败时,再采取图片打点方式上报,这样,能更好的保证数据可靠性和项目的兼容性。

参考资料

  1. 为什么前端监控要用GIF打点open in new window
  2. 前端监控analyticopen in new window
  3. 关于 HTTP GET/POST 请求参数长度最大值的一个理解误区open in new window