优化实战 第 34 期 - 通过 Beacon 实现日志埋点及上报

3,088 阅读2分钟

前端埋点是在产品客户端获取用户行为和使用情况的一种监控方式。通过埋点可以获取到用户行为数据,借助这些数据,可以提升产品使用体验和用户留存率

burying_point.jpg

信标(Beacon)

  • 功能简介

    可以将尽量多的的信息数据传输到服务器

    不需要响应 支持跨域 可携带 Cookie 不支持自定义请求头

  • 性能分析

    异步非阻塞 的数据传输,浏览器可以把 Beacon 请求添加到一个内部的请求队列,在合适的时机发送队列中的请求

    既提升了性能,又改善了用户体验

  • 生活示例

    到某个景点去旅游,有时候会给朋友寄明信片。在上边写一些内容,然后丢进邮箱,之后也不会期待朋友会回寄你一张明信片

  • 注意事项

    通过信标发送的请求,请求方法均为 POST且不支持修改

    信标会根据传入的数据自动设置请求头,但无法自动设置 JSON 数据类型

日志埋点及上报

  • 上报 JSON 数据类型

    const blob = new Blob([JSON.stringify(data)], {
      type: 'application/json; charset=UTF-8',
    })
    navigator.sendBeacon('/api/logs', blob)
    

    通过构建 Blob 对象间接达到设置 Content-Type 的效果

    如果请求成功进入了最终要发送的任务队列,则 navigator.sendBeacon() 返回 true,否则返回 false

  • 用原生装饰器进行装饰设计

    export function sendLog(getUserBehavior) {
      return (target, name, descriptor) => {
        const { value } = descriptor
        descriptor.value = async function(...args) {
          await value.apply(this, args)
          const data = await getUserBehavior.apply(this, [])
          const blob = new Blob([JSON.stringify(data)], {
            type: 'application/json; charset=UTF-8',
          })
          navigator.sendBeacon('/api/logs', blob)
        }
      }
    }
    
  • 装饰器使用

    @sendLog(function() {
      return this.userBehavior  // 用户行为数据收集
    })
    

浏览器兼容性

  • 在现代浏览器和移动端上的支持性相当的理想

    Beacon.png

  • 判断浏览器对 sendBeacon 的支持性

    if (navigator.sendBeacon) {
      console.log('支持,请放心使用!') 
    } else {
      console.log('不支持,请优雅降级!') 
    }
    

    一起学习,加群交流看 沸点