rt:关于sendBeacon描述如下:
navigator.sendBeacon() 方法可用于通过 HTTP POST 将少量数据异步传输到 Web 服务器。
根据以上描述,关键词为POST、异步传输
- 异步:就异步传输来熟,传统的ajax上报,以及常用的img上报都是异步,除非要同步在卸载文档这个时机去发。如果是用户行为事实上报的场景完全可以异步发送。
POST:与传统的img(get)上报相比,优势我理解可能出在数据传输长度上。由于url是发送给服务器的,所以不受浏览器导航栏处理长度限制,而关于服务器处理URI的长度,http1.1规定如下:
HTTP协议不对URI的长度作事先的限制,服务器必须能够处理任何他们提供资源的URI,并且应该能够处理无限长度的URIs,这种无效长度的URL可能会在客户端以基于GET方式的请求时产生。如果服务器不能处理太长的URI的时候,服务器应该返回414状态码(此状态码代表Request-URI太长)。
也就是说只要日志服务器接受这个长度,完全是可以处理的。
然后根据我对img方案的理解,优势如下:
1、支持度高,不存在兼容性问题
2、onError可以处理发送失败的回调进行重试。
综上,我理解只有在监听用户卸载文档着一种场景下的日志上报,sendBeacon有异步优势,此外都是img的应用性要更加广泛一点。
想请教各位大佬什么场景下时必须在卸载文档这个时机去发送的,我目前接触到的场景时退出挽留,但既然已经退出挽留了,img发送也不会造成文档卸载延迟的问题了。还是sendBeacon有什么其他的优势?
时隔一个月我对这个问题有了新的理解,所以也来答一下
希望对同样关注这个问题的人有所帮助:)
在我提出这个问题的时候其实我纠结的是sendBeacon在卸载场景发送数据的必要性
我当时认为如果没有这个必要性,则完全没必要用它取代兼容性更好的new Image方案
事实上我这段时机专注研究性能相关内容,
我注意到在很多场景下卸载时使用sendBeacon是十分必要的
1、为什么在卸载时发送日志?
举个例子来说,在前端性能指标里有一个LCP,统计最大内容绘制,统计最大内容绘制的时间
要知道对于长页面在整个用户访问过程中,最大内容是不断变化的,每变化一次就上报一次显然是不合理的。像这种持续变化的统计内容,只有在用户离开页面时进行上报才最具统计意义。
2、为什么SendBeacon可以解决这个问题?
传统的日志上报有两种分别是Image发送和异步请求发送。但在卸载场景下这两种都有问题
而sendBeacon作为一种单向数据请求则是专门解决这个问题的,同时具备以下特点:
补充:
监听卸载时机(unload)来发送日志是不合理的,有以下两点理由:
1、unload并非是一个稳定触发的事件
2、unload与浏览器关键优化BFCache有冲突关系,可参考以下内容:
针对unload可能出现的问题,更佳的方案是监听pagehide事件与visibilitychange