用户埋点数据上报方法的封装实践(1)

1,593 阅读3分钟

场景

类似talkingdata的sdk已经为我们提供了比较方便的事件上报方法,比如下面这样:

TDAPP.onEvent("活动首页",‘标签名’,params);

针对于简单的数据上报需求,我们完全可以这样直接调用方法,然后完成其功能,但复杂的部分却不行。本文从一些小点说明其必要性。

封装的好处

事件的简化与标准化

在talkingdata中,事件名是以文本值为区分的,而文本值可能会由于使用者的不规范可能会导致错误。为此我们把使用方式进行了如下的约定:

1 定义事件的字典,使用时可以通过引入埋点事件的字典来快速选择期望调用的事件名称

2 在底层调用时,其具体执行的事件名称进行固化,不对外开放

定义时:

export const DATA_REPORT_EVENTS = {
    activityPageIndex:'activityPageIndex',
    activityIn:'activityIn'
}
export const DATA_REPORT_ORI = {
    activityPageIndex:(params){
        TDAPP.onEvent("活动首页",‘’,withParams);
    },
    activityIn:(params){
        TDAPP.onEvent("参加活动",‘’,withParams);
    },
    default:(){
        //codes here
    }
}

使用方式:

import { DATA_REPORT_EVENTS,DATA_REPORT} from 'src/utils/dataReport'
function activityPage extends Comoponent{
    compontentDidMount(){
        //datareport 
        DATA_REPORT(DATA_REPORT_EVENTS.activityPageIndex)
    }
}

环境的区分

上报的需求需要针对线下和线上环境需要进行一定的区分,线下可能不需要上报或者上报的内容有所区分。

dataReport.js 实际暴露方法

import {isProd} from 'src/config/env'
export const DATA_REPORT =  (event,params) => { 
    if (isProd) {
        return DATA_REPORT_ORI[event]?.(params)
    } else { 
        return DATA_REPORT_ORI.default
    }
};

附带数据

显然,在我们的业务中,除了当前的业务信息,有些参数属于全局,也需要我们在上报时进行特定的上报,所以针对这部分我们也会在封装设计时考虑入内(比如用户的ua,唯一id,网络情况等)。

dataReport.js

const ua = navigator.userAgent 
const withParams = {
    userId: sessionStorage.getItem('userId') || 'h5用户' + Math.random() * 1000,
    ua
}

传参params的强化

相比来说,我们针对入参的部分是比较弱化的,这部分如果有需求,可以根据自己的真实需求进行强化。发散思考点如下:

1 提供的params为方法型参数,提供其具有一定逻辑或者算法的事件名

2 为事件调用方提供talkingdata内部的一些数据,比如ua,用户数据,app版本,方便做功能强化

3 params升级为options配置对象,提供上报频率,上报形式等api

上报的高内聚

封装的最核心原因还是要做设计原则上的高内聚,当我们进行一些上报有关的集中处理时,可以在一个文件内完全全局的配置更新,比如上报频率、上报格式等。如果在某个调用的位置直接调用TDAPP.onEvent,会让参数不可控,维护难度大。

小结

之所以当初考虑封装是考虑到:

  • 应用全部监控下来有30+事件,分散在12+页面,30+具体场景,分散维护难度非常大
  • 部分事件其实是一类事件的同质化事件(参数完全相同只是事件名不同)
  • 不同环境以及不同入口有这种策略性质的区分

不会为了设计而设计,当你的场景有一点复杂时,就需要考虑加入封装等设计思想让你的代码更优雅。

语雀连接:www.yuque.com/robinson/fe…