探索埋点基本技术实现

1.为什么要探索

这纯属是我个人意愿,不想不明不白的使用一个东西,不求完全掌握,但想大概知道如何实现。刚进亚运项目小组,接到埋点任务,通过组内学习基本上明白了埋点API的使用,半懂半蒙的完成了埋点任务。
近期手上任务都提测了,闲下来想去探索探索我心中的几个疑问:

  1. 埋点是否会影响性能?
  2. 埋点是Ajax请求吗?
  3. 背后实现思想是什么?

2.如何探索?

本人没有技巧,混迹各种技术社区,俗称水群,总有大佬会说出一些你不知道的web规范、或者说新规范。其实是自己懒,不能想各种大佬一样每周都会去看看web mdn

3.回归主题,埋点技术栈

Beacon API
Beacon API 不会延缓网页卸载,不会严重影响用户体验。
为了解决网页卸载时,异步请求无法成功的问题,浏览器特别实现了一个 Beacon API,允许异步请求脱离当前主线程,放到浏览器进程里面发出,这样可以保证一定能发出。
navigator.sendBeacon()方法可以保证,异步请求一定会发出;
第一个参数是请求的网址,第二个参数是发送的数据
Beacon API 发出的是 **POST **请求。

window.addEventListener('click', function (event) {
  navigator.sendBeacon('/graphql/api/v3/logs', 'event=click');
});
技术栈应用场景
  • 埋点
  • 异常处理
  • 数据收集
  • 性能上报
<html>
  <script>
    // emit non-blocking beacon to record client-side event
    function reportEvent(event) {
      var data = JSON.stringify({
        event: event,
        time: performance.now()
      });
      navigator.sendBeacon('/collector', data);
    }
    
    // emit non-blocking beacon with session analytics as the page
    // transitions to background state (Page Visibility API)
    document.addEventListener('visibilitychange', function() {
      if (document.visibilityState === 'hidden') {
        var sessionData = buildSessionReport();
        navigator.sendBeacon('/collector', sessionData);
      }
    });
  </script>
  
  <body>
    <a href='http://www.w3.org/' onclick='reportEvent(this)'>
     <button onclick="reportEvent('some event')">Click me</button>
   </body>
</html>

缺点:存在兼容性问题;
![image.png](https://img-blog.csdnimg.cn/img_convert/515362c3d105ff6187bbe994d69edef6.png#clientId=uee75fa70-382e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=537&id=u73194602&margin=[object Object]&name=image.png&originHeight=1074&originWidth=2710&originalType=binary&ratio=1&rotation=0&showTitle=false&size=241861&status=done&style=none&taskId=u62877d4d-8716-4063-8d65-c062d658e8d&title=&width=1355)
Beacon 的浏览器支持情况非常好,唯一值得注意的例外是 IE 浏览器(包括 Edge)和 Opera Mini 浏览器。对于大多数情况来说,应该是没有问题的,但在尝试使用 navigator.sendBeacon 时,还是值得做下兼容测试的。如果要兼容低版本浏览器,这时候我们可以采取降级处理:

if (navigator.sendBeacon) {
  // Beacon 代码
} else {
  // 不支持 Beacon。也许降级到 XHR?
}
如何处理降级处理
  1. 采用ajax 上报
  2. 使用image上报

一般来说,都是采用利用image对象的方式上报错误、埋点的;使用图片发送get请求,上报信息,由于浏览器对图片有缓存,同样的请求,图片只会发送一次,避免重复上报。
代码示例

let entry = {};
function report(url, data) {
  if (!url || !data) {
    return;
  }
  // @see http://jsperf.com/new-image-vs-createelement-img
  let image = document.createElement('img');
  image.width = 0;
  image.height = 0;
  let items = [];
  for (let key in data) {
    if (data[key]) {
      items.push(key + '=' + encodeURIComponent(data[key]));
    }
  }
  let name = 'img_' + (+new Date());
  entry[name] = image;
  image.onload = image.onerror = function () {
    console.log(arguments);
    entry[name] =
      image =
      image.onload =
      image.onerror = null;
    delete entry[name];
  };
  image.src = url + (url.indexOf('?') < 0 ? '?' : '&') + items.join('&');
}

image 方式是通过将采集的数据拼接在图片请求的后面,向服务端请求一个 0*0 px 大小的图片实现的,设置它的 src 属性就可以发送数据。这种方式简单且天然可跨域,又兼容所有浏览器,没有阻塞问题是目前比较受欢迎的前端数据上报方式。但由于是** get 请求,对上报的数据量有一定的限制,一般为 2~8 kb**。代码示例如下:

var img = new Image();img.width = 1;img.height = 1;img.src = '/sa.gif?project=default&data=xxx';

HTML5 给 **<img> 标签**新增加了一个** **crossOrigin** 属性**,这个属性决定了_图片获取过程中是否开启跨域功能_。并且如果设置了 **crossOrigin** 这个属性,image 请求中将不带 cookie。代码示例如下:

var img = new Image();img.crossOrigin = "anonymous"

4.总结

4.1 使用img标签get请求

  • 不存在AJAX跨域问题,可做跨域请求
  • 很古老的标签,没有浏览器兼容问题

4.2 navigator.sendBeacon
大部分浏览器都支持navigator.sendBeacon方法。这个方法可以用来发送一些统计和诊断的小量数据,特别时候上报统计场景。

  • 数据可靠,浏览器关闭请求也照样能够发送
  • **异步执行,**不会影响下一页面的加载
  • API使用简单

所以当浏览器支持**navigator.sendBeacon**方法,优先使用该方法,使用img方式降级上报

Beacon API 在将数据从页面发送到服务端方面非常管用,尤其是在日志记录方面。浏览器支持非常广泛,它使你能够无缝地记录数据,而不会对用户的浏览体验和网站性能产生负面影响。 请求的非阻塞性意味着性能比 XHR 和 Fetch 等替代方案好得多

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值