1. 前言

神策分析 Web JS SDK,是一款轻量级用于 Web 端和 H5 端的数据采集埋点 SDK,包含代码埋点、全埋点、可视化全埋点、点击图、触达图、跨域用户打通和弹窗推送等功能。基于 JavaScript 原生语言编写,兼容 Chrome、Firefox、IE(IE6 +) 等所有主流浏览器,并提供不同模式的源码,包括 AMD 模块依赖的 amd.js 源码文件和 ES6 标准的 es6.js 源码文件。

2. 目录结构

Web JS SDK 的源码是独立的 JS 文件,目录如图 2-1 所示:

图 2-1 Web JS SDK 的源码目录

各文件介绍如下:

  1. sensorsdata.full.js:原生 JavaScript 语言的 SDK 未压缩源码;
  2. sensorsdata.min.js:原生 JavaScript 语言的 SDK 压缩源码;
  3. sensorsdata.amd.full.js:AMD 模块依赖方式的 SDK 未压缩源码;
  4. sensorsdata.amd.min.js:AMD 模块依赖方式的 SDK 压缩源码;
  5. sensorsdata.es6.full.js:es6 标准方式的 SDK 未压缩源码;
  6. sensorsdata.es6.min.js:es6 标准方式的 SDK 压缩源码;
  7. heatmap.full.js:原生 JavaScript 语言的 SDK 热力图功能未压缩源码,渲染网页热力图和触达图;
  8. heatmap.min.js:原生 JavaScript 语言的 SDK 热力图功能压缩源码,渲染网页热力图和触达图;
  9. vapph5define.min.js:App 内嵌 H5 页面可视化压缩源码;
  10. vtrack.min.js:Web 网页可视化源码。

3. 数据流程

Web JS SDK 主要是采集页面的数据,并持续稳定地将数据发送到神策分析服务端。主要的数据发送流程如图 3-1 所示:

图 3-1 数据发送流程

SDK 采集的数据,会默认存储到发送队列中。发送队列会按照先进先出的模式逐条发送数据,保证数据发送的顺序。

集成 SDK 的 H5 页面在 App 中,可以通过配置项将 H5 采集的数据上报给 App 端的 SDK(Android SDK 或 iOS SDK)。数据实时通过 WebView 中间层上报给 App 端,App 端可以统一用户标识和其他系统属性字段。

另外,Web 页面采集经常会出现切换页面时发送数据的场景。例如:点击某个按钮跳到了新的页面。此时,采集该按钮的点击事件,就涉及到页面跳转时对原页面代码容器的销毁,从而可能导致该点击事件未发送或者发送失败。

为了解决这一问题经过调研测试发现:如果数据直接写入 localstorage 中,即使在切换页面时也能正常保存。因此,开发了批量发送模式:数据统一写入 localstorage 缓存,然后默认定时 6 秒或者数据量达到 6 条时集中发送一次,发送成功后即从 localstorage 中删除。如果发送失败会继续保留,下次进行发送。

4. 架构解析

4.1 简介

Web JS SDK 致力于高效稳定地采集页面数据,这就需要一个稳定简洁的架构。同时,网页是基于浏览器运行的,浏览器本身并没有多少缓存功能。因此,Web JS SDK 的架构设计中数据默认是采集后立即发送的,这与 App 端的 SDK 是不同的。

4.2 架构图

Web JS SDK 总体架构如图 4-1 所示:

图 4-1 Web JS SDK 总体架构示意图

下面,我们对 Web JS SDK 架构进行详细的解释。

4.3 架构详解

4.3.1 配置模块

页面在引入 Web JS SDK 并进行初始化时,需要配置一些主要的配置项。代码示例如下:

<script>
(function(para) {
    var p = para.sdk_url, n = para.name, w = window, d = document, s = 'script',x = null,y = null;
    w['sensorsDataAnalytic201505'] = n;
    w[n] = w[n] || function(a) {return function() {(w[n]._q = w[n]._q || []).push([a, arguments]);}};
    var ifs = ['track','quick','register','registerPage','registerOnce','clearAllRegister','trackSignup''trackAbtest''setProfile','setOnceProfile','appendProfile''incrementProfile''deleteProfile''unsetProfile','identify','login','logout','trackLink'];
    for (var i = 0; i < ifs.length; i++) {
        w[n][ifs[i]] = w[n].call(null, ifs[i]);
    }
    if (!w[n]._t) {
        x = d.createElement(s), y = d.getElementsByTagName(s)[0];
        x.async = 1;
        x.src = p;
        w[n].para = para;
        y.parentNode.insertBefore(x, y);
    }
})({
    /** 配置项部分 **/
    sdk_url: '在 github 下载新版本的 sensorsdata.min.js ',
    name: 'sensors',
    server_url:'数据接收地址',
    heatmap: {
        //是否开启点击图,default 表示开启,自动采集 $WebClick 事件,可以设置 'not_collect' 表示关闭。
        clickmap:'default',
        //是否开启触达注意力图,not_collect 表示关闭,不会自动采集 $WebStay 事件,可以设置 'default' 表示开启。
        scroll_notice_map:'not_collect'
    }
    /** 配置项部分 **/
});
sensors.quick('autoTrack');
</script>

简要介绍以上这些主要配置项:

  • sdk_url:配置 SDK 源码获取地址,推荐从 GitHub 下载源码到本地,该地址即可配置指向本地文件。或者使用 SDK 发布的 CDN 地址,例如:https://cdn.jsdelivr.net/npm/sa-sdk-javascript@1.15.9/sensorsdata.min.js
  • name:SDK 初始化时,创建的 SDK 对象名。初始化后,即可使用该对象名,调用 SDK 的 API;
  • server_url:数据接收地址。即 SDK 采集的数据最终发往的地址;
  • heatmap:全埋点点击事件和页面停留事件是否采集的配置。通常点击事件开启采集,页面停留事件在需要分析触达图时开启采集。

4.3.2 数据采集模块

数据采集模块提供自动和手动的方式来采集用户在 H5 页面上的行为数据,包括相关页面的预置属性,为最终的用户行为分析和用户画像提供原始数据。具体而言,可分为以下几种方式:

  • 代码埋点:在 SDK 初始化之后,对需要采集的行为数据,调用 track 接口埋点采集;
  • 全埋点:无需开发工程师编写代码即可自动收集用户的行为数据,包括页面浏览事件、元素点击事件和页面停留事件;
  • 可视化全埋点:通过可视化的方式,对网页上的可埋点元素创建新的埋点,并标识显示名或事件名。当用户在点击这些已标记的元素时,会自动采集标识的事件;
  • 预置属性:埋点 SDK 自动采集的一些任何事件都需要携带的最基本的属性(例如屏幕宽高、页面地址、页面标题、前向地址等)。

4.3.3 数据存储模块

数据存储模块提供了对采集的数据进行缓存的功能。Web JS SDK 提供了以下几种数据存储模式:

  • 队列模式:进入页面时,为了不影响正常页面的渲染和执行,通常推荐异步引入 SDK。而异步引入可能导致 SDK 尚未加载就需要采集数据,此时触发的数据就会进入页面队列中缓存。当初始化完成,会按照先进先出的模式从队列中将数据按顺序发送。队列模式提供了两功能:第一是缓存数据,第二是使数据可以按照正常的顺序入库;
  • localstorage 模式:页面采集的数据,会先依次存入 localstorage 中。localstorage 按照默认的每 6 秒或者数据每达到 6 条即集中发送一次数据。当数据发送失败时,并不会将 localstorage 中的数据删除,会再次发送,从而有效避免丢失数据;
  • cookie:会在当前域名下存储一些用户标识数据、首日首次数据和公共属性等。默认存储在根域名的 cookie 下;
  • session:相关 sessionStorage 对于页面变量和属性的存储使用较少,目前经常使用的是 cookie。

4.3.4 数据发送模块

数据发送模块是将 Web JS SDK 采集的数据按照指的方式发送到服务端。主要有以下几种发送方式:

  • 队列发送:默认的发送方式,数据按照采集的顺序依次根据配置的数据接收地址发送到服务端。从技术上,可以选择以下三种请求方式来发送:
    1. image:图片发送也是默认的发送方式,创建一个 image 标签,将数据放在请求的 URL 中发送;
    2. ajax:通过 ajax 异步 POST 请求将数据发送出去;
    3. sendBeacon:这是一种较为高级的数据发送方式,主要用来解决关闭页面发送数据丢失的问题,目前仅支持较新的浏览器版本。
  • 发送给 App SDK:配置 App 与 H5 的打通模式,打通验证通过后,H5 页面 Web JS SDK 采集的数据会传递给 App SDK。然后,按照 App SDK 的数据发送方式,将数据发送到服务端;
  • localstorage 缓存发送:localstorage 缓存中存储了多条数据,通过 ajax 异步方式,将多条数据集中发送到服务端。

4.3.5 工具模块

因为 Web JS SDK 兼容性的要求很高,使用了 JavaScript 原生语法编写,所以需要创建工具模块。这里抽象了很多工具方法来辅助整个 SDK 工作,包括:extend 方法、trim 方法、hashcode 方法、formatDate 方法。工具方法除了实现必要的逻辑,主要还有一些不同浏览器以及不同浏览器版本的兼容处理和异常捕获。工具模块是 Web JS SDK 的底层和基础,所有的数据采集和传输逻辑,都是由这些工具方法来帮助实现的。

4.3.6 日志模块

集成 Web JS SDK 后,SDK 默认自动开启日志输出功能方便调试,可以在控制台看到以下日志示例:

每个数据采集详情,都会依次通过日志模块打印在控制台中。调试的时候可以通过控制台日志,监控和调试每个数据采集的准确性。日志可以通过 show_log : false 配置来关闭,如果是线上正式环境,建议关闭日志模块。日志模块可以有效地检测和验证埋点数据的正确性,尤其在集成埋点阶段,对照神策分析师设计的埋点方案,可以逐一进行对比每个埋点的具体数据采集情况,极大地提高了埋点工作的效率。

4.3.7 渲染模块

渲染模块包括点击图和触达图的渲染,这些功能集中在 heatmap.js 中。主要是将元素点击数据和页面停留事件,经过计算后将效果渲染在页面上,达到直观分析数据结果的目的:

  • 点击图:是将页面中访客的点击数据直观地渲染到页面上,可以直接看到页面中哪些元素被访客点击并且点击的比例是多少,以及点击都集中在哪些位置;
  • 触达图:是页面有垂直滚动条时,来渲染访客浏览页面的深度数据。默认首屏页面展示的是 100%,页面越深,一般触达的访客占比也越小。

5. 总结

本文简要介绍了当前 Web JS SDK 的主要架构,后续还会对架构中的每个模块进行单独地分析和说明。

另外,随着客户需求的增加和技术的更新,Web JS SDK 的架构也会进行调整和优化。目前,计划将 Web JS SDK 中不同功能拆分成独立的组件,这样可以基于不同客户的需求,提供最精简的、组件化的 SDK。