埋点分析
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的生命周期进行埋点,并且进行定时发送,保证了不会太影响性能,写这篇文章的作用一个方面是为了加深自己对这些知识的理解,一方面希望在这里能起到抛砖引玉的作用,能学到更多的知识。