Web页面埋点的一次项目经验

什么是埋点

  • 所谓“埋点”,是数据采集领域(尤其是用户行为数据采集领域)的术语,指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。
  • 帮助定义和获取分析人员真正需要的业务数据及其附带信息。
  • 在应用中特定的流程里收集一些信息,用来跟踪应用使用的状况,后续用来进一步优化产品或是提供运营的数据支撑,包括访问(Visits),访客(Visitor),停留时间(Time On Site),页面查看(Page Views,又称为页面浏览)和跳出率(Bounce Rate,又可称为蹦失率)。
  • 这样的信息收集可以大致分为两种:页面统计(track this virtual page view),统计操作行为(track this button by an event)。

常用术语

  1. PV(Page View):页面浏览量或者点击量:某个用户某次对网站中的某个网页进行访问,就记录一次PV。
  2. UV(Unique Visitor):通过互联网访问、浏览这个网页的自然人。访问网站的一台客户端为一个访客,0:00-24:00内相同的客户端只被计算一次。一天内同一个访客多次访问仅计算一个UV

埋点的方式

  1. 在产品开发中注入代码,并搭建起相应的后台查询
  2. 使用三方统计工具,如友盟、百度移动、魔方、App Annie、talking data等。如果你的数据来自第三方,那你使用的工具也应该是第三方统计工具,后续没啥数据产品了。

公司Hybird App里的Web项目埋点经验

业务场景

  • 在App里某业务线嵌入的Web项目
  • 埋点和BI部门对接
  • 没有使用第三方平台

js-base64

  1. Base64是基于64个可打印字符来表示二进制数据的表示方法。
  2. 用处往往并不是为了防止信息泄露,而且为了方便传输,进过Base64编码后的信息会比原始信息长,每6个比特为一个单元,对应某个可打印字符。而3个字节占用24个比特,对应于4个Base64单元,即3个字节可由4个可打印字符来表示,所以长度大概是4/3倍。
  3. 其源码里包含
    • key:一个String字符串,长度为64
    • encode方法:加密算法;
    • decode方法:解密算法;
  4. 使用方法很简单

    1
    npm i --save js-base64
    1
    2
    3
    4
    import { Base64 } from 'js-base64'

    var result = Base64.encode(str)
    var result2 = Base64.decode(result)

protobufjs

  1. 现在HTTP通信我们一般采用JSON格式,这次公司的BI采用了不一样的数据传输格式。
  2. Protocol Buffers是Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。采用类似TLV(tag,length,value)的编码方式,输出一段字节数组,是一种二进制格式的协议。它不依赖于语言和平台并且可扩展性极强。现阶段官方支持C++、JAVA、Python等三种编程语言,但可以找到大量的几乎涵盖所有语言的第三方拓展包。
  3. 数据体积方面的优势是比较明显的。JSON文件的问题在于无效数据太多(这里指每传一个对象就有一套键值对,键名都是重复的),这些内容大量重复出现,使得数据体积较大。而protobuf文件,它使用一个唯一的id(数字)来代替JSON里复杂的key,这样只要数据发送方和接受方都按约定的同一套“模板”来解析数据,就可以大大缩短报文体积。

    1
    2
    3
    4
    [
    {"Name": "zhangsan", "Gender": 0, "Age": 18},
    {"Name": "lisi", "Gender": 1, "Age": 19}
    ]
    1
    2
    3
    4
    5
    message Person {
    required string Name = 1;
    optional int32 Gender = 2;
    optional int32 Age = 3;
    }
  4. protobufjs是基于ByteBuffer.js的Protocol Buffers的纯Javascript实现。主要功能是解析.proto文件,构建message类,和进行简单的编码、解码。

  5. protobufjs依赖包了解一下,网络世界中的数据传输从一开始的XML到JSON现在越来越多的人开始向protobuf转变
  6. 简单的说,protobufjs发挥的作用就是protobuf数据和js对象的相互转换
  7. 使用方式:(前端模版用JSON)

    1. 首先要定义好一个json模版

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      // awesome.json
      {
      "nested": {
      "AwesomeMessage": { // 怎么定位?下面就会看到
      "fields": {
      "awesomeField": {
      "type": "string", // 类型要求
      "id": 1 // 就是用这种id来替代key
      }
      }
      }
      }
      }
    2. JSON的结构,粗体标识的是必须的:

      | type (t) | extends | type-specific properties
      |:—:|:—:|:—:|
      | ReflectionObject | | options
      | Namespace | ReflectionObject| nested
      | Root | Namespace | nested
      | Type | Namespace | fields
      | Enum | ReflectionObject| values
      | Field | ReflectionObject| rule, type, id
      | MapField | Field | keyType
      | OneOf | ReflectionObject| oneof (array of field names)
      | Service | Namespace | methods
      | Method | ReflectionObject|type, requestType, responseType, requestStream, responseStream

    • JSON文件可以被load也可以以模块的规范来引用,比如

      1
      2
      var jsonDescriptor = require("./awesome.json");  // exmplary for node
      var root = protobuf.Root.fromJSON(jsonDescriptor)
    • 使用可以有多种方式,用js api的方式,根据官方提供的:

      1
      2
      3
      4
      5
      6
      7
      const AwesomeMessage = root.lookupType("awesomepackage.AwesomeMessage"); // 定位
      let message = AwesomeMessage.create({ awesomeField: "hello" }); // 传入参数,根据上面定位的模版生成
      console.log(`message = ${JSON.stringify(message)}`);
      let buffer = AwesomeMessage.encode(message).finish(); // encode刚才生成的东西,这个就可以作为data发给后端了
      console.log(`buffer = ${Array.prototype.toString.call(buffer)}`);
      let decoded = AwesomeMessage.decode(buffer);
      console.log(`decoded = ${JSON.stringify(decoded)}`);