为了更好地了解用户对产品的使用状况,业务中,咱们常常会收到埋点统计的需求,好比:我要说话前端
不管是移动端仍是 PC 端,相信不少朋友都遇到了这么几个十分让人头疼的问题:我要说话git
若是咱们把这样的数据交给了产品同窗,可能会让他们对用户行为产生错误的认知,必定程度上影响产品的下一步改善。我要说话github
上面提到的问题,从技术角度能够概括为两点:我要说话编程
针对第一点,几率较小,通常的处理方式就是,不要把统计脚本参合到其余脚本中,单独加载,而且放在前头,让它优先加载。不少公司的作法是,不让开发者关心统计脚本的加载,用户请求页面的时候,Nginx 会在 Body 开始标签位置注入一段脚本。我要说话跨域
对于问题二,处理方案就有不少了。我要说话数组
1. 阻塞式的 Ajax 请求我要说话浏览器
还记得 XMLHttpRequest::open
方法的第三个参数吧,若是设置为 false 就是同步加载,我要说话app
window.addEventListener('unload', function(event) { |
阻塞页面关闭,固然能够在 readState
为 2 的时候就 abort 请求,由于咱们不关心响应的内容,只要请求发出去就好了。我要说话异步
2. 暴力的死循环我要说话函数
原理跟上面相似,只不过是使用一个空的死循环阻塞页面关闭,我要说话
window.addEventListener('unload', function(event) { |
3. 发一个图片请求阻塞我要说话
大部分浏览器都会等待图片的加载,趁这个机会把统计数据发送出去我要说话
window.addEventListener('unload', function(event) { |
以上提到的几个方案都是一个原理,让浏览器继续保持阻塞状态,等数据发送出去后再跳转,这里存在的问题是:我要说话
是否有更好的方案解决这个问题呢,前端同窗秉着「小强精神」也提出了两个可实践的方案。我要说话
不就是埋点统计数据嘛,非得在当前页面发送出去?优化方案的思路具备必定的跳跃性,咱们考虑将数据在下跳页中发送,那么问题就转换为,如何将数据传递给下跳页?我要说话
对于连接点击量的统计,咱们能够将连接信息经过 url 传递给下跳页,传递思路以下:我要说话
1. url 传参我要说话
经过数组标识一个连接的位置信息,如 [站点id,页面id,模块id,连接index]
,经过四个参数能够唯一标识连接位置属性,使用 URL param 参数将数组数据传递给下跳页,等待由下跳页将数据发送出去。我要说话
这里存在的问题是,下跳页中必须部署一样的统计脚本,但对一个系统来讲,这是很容易作到的。咱们也不会在本身的网页上放其余网站的连接吧,因此整个数据的统计都在一个闭环内。我要说话
2. 经过 window.name
传递数据我要说话
window.name
是浏览器给咱们开放的一个接口,设置该属性的值后,即使页面发生了跳转,这个值依然不会变化,而且能够跨域使用。我要说话
这里存在的问题是,该属性可能被开发者用于其余途径。咱们能够限制开发者直接使用window.name
,封装接口,经过接口调用,如 aralejs 提供的 nameStorage,我要说话
nameStorage.setItem(key, value); |
储存形式为:我要说话
scheme nameStorage datas |
以上虽然基本解决了数据丢失和体验差的问题,可是这也很大程度依赖于开发者的编程习惯,如不能随便玩耍 window.name
;也对系统有必定的要求,必须在全部页面上部署一样的埋点脚本。我要说话
上面提到的各类方案,不乏黑科技,然而存在的问题仍是一大堆,若是团队的开发者执行力不够,中途容易出现各类麻烦。因此真正可以解决这个问题的,必然仍是浏览器自己!我要说话
为何不能给用户提供这样一个 API,即便页面跳转了,也可以将上个页面的请求发出去呢?庆幸的是,W3C 工做组也想到了这个问题,提出了 Beacon API
的 草案。我要说话
Beacon API
容许开发者发送少许错误分析和上报的信息,它的特色很明显:我要说话
sendBeacon
函数挂在在 navigator 上,在 unload 以前,这个函数必定是被初始化了的。其使用方式为:我要说话
window.addEventListener('unload', function(event) { |
navigator.sendBeacon(url, data);
,第一个参数为数据上报的地址,第二个参数为要发送的数据,支持的数据格式有:ArrayBufferView, Blob, DOMString, 和 FormData。我要说话
Beacon
的还有一个很是实用的移动端使用场景,当用户从浏览器切换到其余 app 界面或者 Home 屏的时候,部分浏览器默认会中止页面脚本的执行,若是在这个时候使用了 unload 时间,可能会让你失望,由于 unload 事件并不会触发,此时,Beacon
就派上用途了,它是不会受影响的。我要说话
本文是对页面打点丢失问题的简单探讨,枚举了咱们一般会用到的一些解决方案,可能不是很完善,若是你有更好的建议,能够提出来。我要说话
不少问题,咱们绞尽脑汁,可能不多会考虑,这个问题是否是应该有咱们来解决,或者说这个问题交给谁处理是最恰当的。本文的探讨能够看到,浏览器自己才是最好的问题解决方,当网站流量变大以后,上面提到的丢失问题就更加明显,这也迫使浏览器自己作了改善,天然也在情理之中