小程序埋点初探 / 前端埋点 / PV埋点

埋点分析

1.什么是埋点

百度上的解释:埋点分析,是网站分析的一种常用的数据采集方法,指在需要采集数据的"操作节点"将数据采集的程序代码附加在功能程序代码中,对操作节点上用户行为或事件进行捕获、处理和发送相关技术及其实施过程。 简单来说:就是通过代码收集用户的操作,将这些数据存储起来,用于后期分析。

2.前端怎么埋点

a.代码埋点

最简单也是最暴力的埋点方式,就是在需要埋点的地方加上埋点的代码,这会导致前期开发和维护成本很大,如果需要收集的信息很少,可以使用这种埋点方式。

b.全埋点/无埋点

利用SDK或者对框架的生命周期、事件进行拦截,在一个地方统一的埋点,可以减少很多代码的维护和开发,但是会影响性能。

c.可视化埋点

通过在应用程序或网站中使用可视化工具来捕获和分析用户行为数据。可视化埋点不需要手动添加跟踪代码或日志记录,而是通过可视化工具来实现数据采集和分析。

3.全埋点在小程序中实现PV和UV

a.背景/需求

公司要求在web端、小程序端、H5端进行埋点,统计PV和UV,用于对用户习惯的分析。我刚好是实现小程序的埋点功能,并且做了调研,了解了小程序自带的web分析,发现不适用我们的需求,代码埋点又会造成维护的困难,最后决定使用无埋点方案。

b.具体实现

小程序的Page类是可以进行重写的,因此我决定重写Page类中的生命周期。 一开始的想法是在onShow里面写进入页面的逻辑,在onHide里面写统计页面存在时间的逻辑,后面发现onHide并不能很好的触发,例如返回navigateTo和navigateBack进入和退出页面,并不会触发onHide的事件,于是最终决定全部在onShow实现。

首先重写Page的onShow生命周期

新建一个page-extend.js,并且在app.js 里面require('/路径/page-extend')

kotlin 复制代码
/**
 *
 * Page扩展函数
 *
 * @param {*} Page 原生Page
 */
 //buryPointFun是上报数据的方法
import {buryPointFun} from "./util"

const pageExtend = Page => {
  return object => {
    // 导出原生Page传入的object参数中的生命周期函数

    // 公共的onShow生命周期函数
    object.onShow = function (options) {
      //用于执行Page原生的onShow
      if (typeof onShow === 'function') {
        onShow.call(this, options)
      }
    }
    return Page(object)
  }
}

// 获取原生Page
const originalPage = Page
// 定义一个新的Page,将原生Page传入Page扩展函数
Page = pageExtend(originalPage)
记录进入当面的页面
typescript 复制代码
/**
 *
 * Page扩展函数
 *
 * @param {*} Page 原生Page
 */
 //buryPointFun是上报数据的方法
import {buryPointFun} from "./util"

const pageExtend = Page => {
  return object => {
    // 导出原生Page传入的object参数中的生命周期函数

    // 公共的onShow生命周期函数
    object.onShow = function (options) {
      const pages = getCurrentPages();
      const newPages = pages.map(item=>item.route);
       //拿到最后一个页面路由(即当前页面)
      pageObject = {
        route:newPages[newPages.length-1],
        beginTime:time
      }
      //存到埋点队列
      buryPointFun({
        pageObject
      })
      console.log(`开始进入${pageObject.route}页面`,pageObject)
      //用于执行Page原生的onShow
      if (typeof onShow === 'function') {
        onShow.call(this, options)
      }
    }
    return Page(object)
  }
}

// 获取原生Page
const originalPage = Page
// 定义一个新的Page,将原生Page传入Page扩展函数
Page = pageExtend(originalPage)
记录离开上个页面的时间(这里利用了onShow和page列表,并且用了一个对象去做记录)
typescript 复制代码
/**
 *
 * Page扩展函数
 *
 * @param {*} Page 原生Page
 */
 //buryPointFun是上报数据的方法
import {buryPointFun} from "./util"
//用于记录当前页面的数据,当页面切换时可以统计时间
let pageObject = {
  route:"",
  beginTime: 0
}
const pageExtend = Page => {
  return object => {
    // 导出原生Page传入的object参数中的生命周期函数

    // 公共的onShow生命周期函数
    object.onShow = function (options) {
      const pages = getCurrentPages();
      const newPages = pages.map(item=>item.route);
      const time = new Date().valueOf()
      if(pageObject.route){
        const existTime = time-pageObject.beginTime
        console.log(`${pageObject.route}存在时间`,existTime)
        buryPointFun({
          page:pageObject.route,
          existTime
        })
      }
       //拿到最后一个页面路由(即当前页面)
      pageObject = {
        route:newPages[newPages.length-1],
        beginTime:time
      }
      //存到埋点队列
      buryPointFun({
        pageObject
      })
      console.log(`开始进入${pageObject.route}页面`,pageObject)
      //用于执行Page原生的onShow
      if (typeof onShow === 'function') {
        onShow.call(this, options)
      }
    }
    return Page(object)
  }
}

// 获取原生Page
const originalPage = Page
// 定义一个新的Page,将原生Page传入Page扩展函数
Page = pageExtend(originalPage)
最后看一下buryPointFun实现

实现思路:为了保证系统的性能,并没有做到一个埋点上传一次,而是放到一个队列,并且缓存到本地,当触发某些条件,例如3秒上传一次,或者数据达到了十条上传一次,这里还利用了闭包,保证了对象的唯一。

javascript 复制代码
export const buryPointFun = (()=>{
  if(Env.isBuryPoint){
    let timer = null
    timer = setInterval(()=>{
      const buryPointList = wx.getStorageSync('buryPoint') ||[]
      if(buryPointList.length>0){
        //发送数据
        console.log("发送数据-埋点",buryPointList)
        //清除数据
        wx.setStorageSync('buryPoint', [])
      }

    },10*1000)
    return function(config){
        const buryPointList = wx.getStorageSync('buryPoint') ||[]
        buryPointList.push(config)
        wx.setStorageSync('buryPoint', buryPointList)
        console.log("存储埋点数据",buryPointList)
        if(buryPointList.length>=10){
          //发送数据
          console.log("发送数据-埋点",buryPointList)
          //清除数据
          wx.setStorageSync('buryPoint', [])
        }
    }
  }
})()

总结

以上就是小程序进行pv和uv埋点的代码操作,主要利用Page的生命周期进行埋点,并且进行定时发送,保证了不会太影响性能,写这篇文章的作用一个方面是为了加深自己对这些知识的理解,一方面希望在这里能起到抛砖引玉的作用,能学到更多的知识。

相关推荐
天下无贼!34 分钟前
2024年最新版Vue3学习笔记
前端·vue.js·笔记·学习·vue
Jiaberrr34 分钟前
JS实现树形结构数据中特定节点及其子节点显示属性设置的技巧(可用于树形节点过滤筛选)
前端·javascript·tree·树形·过滤筛选
赵啸林37 分钟前
npm发布插件超级简单版
前端·npm·node.js
罔闻_spider1 小时前
爬虫----webpack
前端·爬虫·webpack
吱吱鼠叔1 小时前
MATLAB数据文件读写:1.格式化读写文件
前端·数据库·matlab
爱喝水的小鼠1 小时前
Vue3(一) Vite创建Vue3工程,选项式API与组合式API;setup的使用;Vue中的响应式ref,reactive
前端·javascript·vue.js
WeiShuai2 小时前
vue-cli3使用DllPlugin优化webpack打包性能
前端·javascript
Wandra2 小时前
很全但是超级易懂的border-radius讲解,让你快速回忆和上手
前端
ice___Cpu2 小时前
Linux 基本使用和 web 程序部署 ( 8000 字 Linux 入门 )
linux·运维·前端
JYbill2 小时前
nestjs使用ESM模块化
前端