npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

hualctracker

v1.0.19

Published

生成编译对应的埋点SDK

Downloads

4

Readme

LinkOffice-Tracker

引言

前端埋点sdk的方案十分成熟,之前用的都是公司内部统一的埋点产品,从前端埋点和数据上报后的可视化查询全链路打通。但是在最近的一个私有化项目中就遇到了问题,因为服务都是在客户自己申请的服务器上的,需要将埋点数据存放到自己的数据库中,同时前端埋点的功能简洁,不需要太多花里胡哨的东西。公司内部的埋点产品不适用,外部一些十分成熟的埋点产品又显得太臃肿,因此着手自己在开源包的基础上封了一个简单的埋点sdk,简单聊聊其中的一些功能和解决方式。

云业务模块appid

| 模块 | 模块名称 | Appid | | ---------------- | --------------- | ----- | | 门户 | portal | 10001 | | | | | | | | | | 公文管理 | gongwen | 10050 | | 公文管理移动端 | gongwen-mobile | 10051 | | | | | | | | | | 业务生成器 | ofs | 10100 | | 业务生成器移动端 | ofs-mobile | 10101 | | | | | | 信息发布 | xinxi | 10150 | | 信息发布移动端 | xinx-mobile | 10151 | | | | | | 文档中心 | document | 10200 | | 文档中心移动端 | document-mobile | 10201 | | | | | | | | | | | | |

饮水思源

功能

对于产品来说,埋点上首要关心的是页面的pv、uv,其次是一些重要操作(以点击事件为主)的频率,针对某些曝光量高的页面,可能也会关注页面的热力图效果。满足这些关键功能的基础上,同时把一些通用的用户环境参数(设备参数、时间参数、地区参数)携带上来,发送请求到指定的后端服务接口,这就基本上满足了一个埋点skd的功能。

大概就具备了以下一些功能:

1.页面加载完成自动上报pv、uv 2.支持用户手动上报埋点 3.上报时默认携带时间、设备等通用参数 4.支持用户自定义埋点参数上报 5.支持用户标识设置 6.支持自动开始热力图埋点(页面中的任意点击会自动上报) 7.支持dom元素配置化的点击事件上报 8.支持用户自定义埋点上报接口配置

使用说明

  1. 配置npm的源为:云效

  2. 安装包

    npm install @linkofffice/tracker
  3. 配置环境

    1、创建文件:\src\tracker\index.js

    import Vue from 'vue'
    import Tracker from '@linkoffice/tracker'
       
    Vue.use(Tracker)
    const tracker = new Tracker({
      masterReport: true, // 总开关,控制是否上报,默认开启
      appid: '100001', // 应用标识,用来区分埋点数据中的应用
      uuid: '', // 设备标识,自动生成并存在浏览器中,
      extra: {}, // 用户自定义上传字段对象
      enableTrackerKey: true, // DOM上报
      enableHeatMapTracker: false, // 是否开启热力图自动上报暂不开启
      enableLoadTracker: true, // 是否开启页面加载自动上报,适合多页面应用的pv上报
      enableHistoryTracker: true, // 是否开启页面history变化自动上报,适合单页面应用的history路由
      enableHashTracker: true, // 是否开启页面hash变化自动上报,适合单页面应用的hash路由
      requestUrl: '/tracker' // 埋点请求后端接口
    })
       
    export default tracker

    2、引入main.js文件

    import tracker from './tracker'
       
    new Vue({
      router,
      store,
      tracker, // 注入vue
      render: h => h(App)
    }).$mount('#app')
  4. 设置登录人员信息

    在有身份信息后请第一时间设置登录人的ID

    this.$tracker.setUserId('1001')
  5. js上报

    在代码中直接加入对应的方法

    // 埋点发送方法,3个参数分别是:事件类型,事件标识,上报数据
    this.$tracker.sendTracker('click', 'module1', { a: 1, b: 2, c: 'ccc' })
  6. DOM上报

    需开启enableTrackerKey,直接在DOM 对象上设置属性tracker-key值为对应的eventId

    <Button type="submit" tracker-key="{{eventId}}">确定</Button>

配置参数

| 参数 | 说明 | 类型 | 默认值 | | -------------------- | ------------------------------------------------------------ | -------- | ------ | | masterReport | 上报总开关 | Boolean | true | | appid | 应用标识 | string | | | uuid | 设备标识,自动生成并存在浏览器中, | string | uuid | | extra | 用户自定义上传字段对象 | json对象 | {} | | enableTrackerKey | dom点击上报 | Boolean | false | | enableHeatMapTracker | 是否开启热力图自动上报 | Boolean | false | | enableLoadTracker | 是否开启页面加载自动上报,适合多页面应用的pv上报 | Boolean | false | | enableHistoryTracker | 是否开启页面history变化自动上报,适合单页面应用的history路由 | Boolean | false | | enableHashTracker | 是否开启页面hash变化自动上报,适合单页面应用的hash路由 | Boolean | false | | requestUrl | 埋点请求后端接口 | string | |

可用事件

| 事件 | 说明 | 参数 | | ----------- | ---------------- | ---------------------------- | | setUserId | 设置登录人ID信息 | string | | sendTracker | 埋点发送方法 | 事件类型,事件标识,上报数据 |

上报参数说明

| 字段 | 简写 | 含义 | | -------------- | ---- | -------------------- | | appid | api | 应用标识 | | uuid | uid | 设备id | | branchid | bid | 分支ID | | eventType | et | 事件类型 | | eventId | ei | 事件ID | | userId | uei | 用户id | | browser | br | 浏览器类型 | | browserVersion | bv | 浏览器版本 | | engine | eng | 浏览器引擎 | | language | lang | 语言 | | device | dv | 客户端 | | os | os | 设备类型 | | osVersion | osv | 设备版本号 | | eventTime | eti | 埋点上报时间 | | title | tit | 页面标题 | | url | ul | 页面地址 | | domPath | dp | 事件触发的dom | | offsetX | ox | 事件触发的dom的x坐标 | | offsetY | oy | 事件触发的dom的y坐标 | | extra | | 用户自定义字段对象 |

更新说明

  1. 修改代码

  2. 编译代码

    npm run build
  3. 推送私有化npm 说明

    npm publish

代码说明

pv统计

pv的统计根据业务方需求有两种方式,第1种是完全由业务方自己来控制,在页面加载或变化的时候调用通用埋点方法来上报。第2种是通过初始化配置开启自动pv统计,由sdk来完成这一部分的埋点上报。第1种方式非常好理解,就不具体展开来,下面具体说一些sdk自动埋点统计的实现原理:

对于多页面应用,每次进一个页面就是一次pv访问,所以配置了 addEventListener = true 之后,sdk内部会对浏览器的load事件进行监听,当页面load后进行埋点上报,所以本质上是对浏览器load事件的监听和处理。

对于单页面应用来说,只有第一次加载页面才会触发load事件,后续路由的变化都不会触发。因此除了监听load事件外,还需要根据路由的变化监听对应的事件,单页面应用有两种路由模式:hash模式和history模式,两者的处理方式有所差异:

  • hash模式,单页面应用的hash路由实现原理是通过改变url的hash值来实现无页面刷新的,hash的变化会触发浏览器的hashchange事件,因此埋点sdk中只需要对hashchange事件进行监听,就可以在事件触发时进行埋点上报。
  • history模式,单页面应用的history路由实现的原理是通过操纵浏览器原生的history对象,history对象中记录着浏览器会话的历史记录,并提供了一些方法对会话栈进行管理。如:
history.go(): 
history.forward():
history.back():
history.pushState():
history.replaceState():

和hash模式不同的是,上述的history.go、history.forward 和 history.back 3个方法会触发浏览器的popstate事件,但是history.pushState 和 history.replaceState 这2个方法不会触发浏览器的popstate事件。然而主流的前端框架如react、vue中的单页面应用history模式路由的底层实现是依赖 history.pushState 和 history.replaceState 的。因此并没有原生的事件能够被用来监听触发埋点。为了解决这个问题,可以通过改写history的这两个事件来实现新事件触发:

const createHistoryEvent = function(type) {
    var origin = history[type];
    return function() {
        var res = origin.apply(this, arguments);
        var e = new Event(type);
        e.arguments = arguments;
        window.dispatchEvent(e);
        return res;
    };
};

history['pushState'] = createHistoryEvent('pushState');
history['replaceState'] = createHistoryEvent('replaceState');

改写完之后,只要在埋点sdk中对pushState和replaceState事件进行监听,就能实现对history模式下路由变化的埋点上报。

uv统计

埋点对pv的支持是必不可少的,sdk会提供了一个设置用户uid的方法setUserId暴露给业务使用,当业务平台获取到登录用户的信息后,调用该方法,则会在后续的埋点请求中都带上uid,最后在埋点分析的时候以该字段进行uv的统计。但是这样的uv统计是不准确的,因为忽略了用户未登录的情况,统计出来的uv值是小于实际的,因此需要在用户未登录的情况下也给一个区分标识。这种标识常见的有以下几种方式:

  • 用户ip地址
  • 用户第一次访问时,在cookie或localStorage中存储一个随机生成的uuid
  • 浏览器指纹追踪技术,通过获取浏览器具有辨识度的信息,进行一些计算得出一个值,那么这个值就是浏览器指纹,辨识度的信息可以是UA、时区、地理位置或者是你使用的语言等等

这几种方式各自存在着自己的一些弊端,ip地址准确度不够,比如同一个局域网内的共享一个ip、代理、动态ip等原因都会造成数据统计都错误。cookie和localStorage都缺陷是用户可以主动去清除。而浏览器指纹追踪技术的应用目前并不是很成熟。

综合考虑后,sdk中采用了localStorage技术,当用户第一次访问时,会自动生成一个随机的uuid存储下来,后续的埋点上报中都会携带这个uuid,进行用户信息都标识。同时如果业务平台调用了setUserId方法,则会把用户id存储到uid字段中。最后统计uv都时候,根据实际情况参考uid或者uuid字段,准确的uv数据,应该是介于uid和uuid之间的一个数值。

热力图上报

热力图埋点的意思是:监听页面中任意位置的用户点击事件,记录下点击的元素和位置,最后根据点击次数的多少,得到页面中的点击分布热力图。这一块的实现原理比较简单,只需要在埋点sdk中开启对所有元素对点击事件对监听即可,比较关键的一点是要计算出鼠标的点击x、y位置坐标,同时也可以把当前点击的元素名称或者class也一起上报,以便做更精细化的数据分析。

dom点击上报

dom点击上报就是通过在dom元素上添加指定属性来达到自动上报埋点数据的功能。具体来说就是在页面的dom元素,配置一个 tracker-key = 'xxx' 的属性,表示需要进行该元素的点击上报,适用于上报通用的埋点数据(没有自定义的埋点数据),但是又不需要热力图上报的程度。这种配置方式是为了节省了要主动调用上报方法的步骤,但是如果埋点中有自定义的数据字段,还是应该在代码中去调用sdk的埋点上报方法。实现的方式也很简单,通过对body上点击事件进行全局监听,当触发事件时,判断当前event的getAttribute('tracker-key')值是否存在,如果存在则说明需要上报埋点事件,调用埋点上报方法即可

上报埋点方式

埋点上报的方式最常见的是通过img标签的形式,img标签发送埋点使用方便,且不受浏览器跨域影响,但是存在的一个问题就是url的长度会收到浏览器的限制,超过了长度限制,就会被自动截断,不同浏览器的大小限制不同,为了兼容长度限制最严格的IE浏览器,字符长度不能超过2083。 为了解决img上报的字符长度限制问题,可以使用浏览器自带的beacon请求来上报埋点,使用方式为:

navigator.sendBeacon(url, data);

这种方式的埋点上报使用的是post方法,因此数据长度不受限制,同时可将数据异步发送至服务端,且能够保证在页面卸载完成前发送请求,即埋点的上报不受页面意外卸载的影响,解决了ajax页面卸载会终止请求的问题。但是缺点也有两个:

1.存在浏览器的兼容性,主流的大部分浏览器都能支持,ie不支持。 2.需要服务端配置跨域

因此可以将这两种方式结合起来,封装成统一的方法来进行埋点的上报。优先使用img标签,当字符长度超过2083时,改用beacon请求,若浏览器不支持beacon请求,最好换成原生的ajax请求进行兜底。(不过如果不考虑ie浏览器的情况下,img上报的方式其实已经够用,是最适合的方式)

const reportTracker = function (url, data) {
    const reportData = stringify(data);
    let urlLength = (url + (url.indexOf('?') < 0 ? '?' : '&') + reportData).length;
    if (urlLength < 2083) {
      imgReport(url, data);
    } else if (navigator.sendBeacon){
      sendBeacon(url, data);
    } else {
      xmlHttpRequest(url, data);
    }
}