前端埋点实现方案

article/2025/10/8 8:35:14

前言

领导今天又来活了😣,要记录每个页面的停留时间,以及页面的操作,是由哪个页面跳转过来的,给每个页面生成GUID上报给服务端,并且需要携带设备型号和设备唯一标识🙄

名称解释

UV(Unique visitor)

是指通过互联网访问、浏览这个网页的自然人。访问您网站的一台电脑客户端为一个访客。00:00-24:00内相同的客户端只被计算一次。一天内同个访客多次访问仅计算一个UV

IP(Internet Protocol)

独立IP是指访问过某站点的IP总数,以用户的IP地址作为统计依据。00:00-24:00内相同IP地址之被计算一次。

UV与IP区别

如:你和你的家人用各自的账号在同一台电脑上登录新浪微博,则IP数+1,UV数+2。由于使用的是同一台电脑,所以IP不变,但使用的不同账号,所以UV+2

PV(Page View)

即页面浏览量或点击量,用户每1次对网站中的每个网页访问均被记录1个PV。用户对同一页面的多次访问,访问量累计,用以衡量网站用户访问的网页数量。

VV(Visit View)

用以统计所有访客1天内访问网站的次数。当访客完成所有浏览并最终关掉该网站的所有页面时便完成了一次访问,同一访客1天内可能有多次访问行为,访问次数累计。

PV与VV区别

如:你今天10点钟打开了百度,访问了它的三个页面;11点钟又打开了百度,访问了它的两个页面,则PV数+5,VV数+2.PV是指页面的浏览次数,VV是指你访问网站的次数。

埋点分类

代码埋点

通过代码的方式在页面中嵌入逻辑🎨,比如捕获一个点击事件,在这个点击事件之前加入代码埋点⛑,上报给后台🥐。国内已经有很多成型的服务商了如友盟,百度统计等🌯,都提供了比较成型的方案🎨,并可以在后台管理系统中查看比较详细的数据分析🧵,但是肯定会有领导想要把这些事情掌握在自己的手中,我们就只能通过自身开发来实现代码埋点🍞。

  • 优点:
  • 控制精准,可以非常精确地选择什么时候发送数据。
  • 传递多样化自定义属性、自定义事件,传递比较丰富的数据到服务端。
  • 缺点:
  • 埋点代价比较大,每一个控件的埋点都需要添加相应的代码,不仅工作量大,必须是技术人员才能完成。
  • 更新的代价比较大,每一次更新埋点方案,都必须改代码。

可视化埋点

个人理解的可视化埋点应该是肯定需要第三方的服务商支持🍜,不会有做专门业务的公司去做可视化埋点的解决方案。可视化埋点开发人员除集成采集可视化SDK 外👜,不需要额外去写埋点代码🍠,而是由业务人员或运营人员通过访问分析平台的圈选功能🤔,来“圈”出需要对用户行为进行捕捉的控件🎪,并给出事件命名🚘。圈选完毕后,这些配置会同步到各个用户的终端上😮,由采集SDK按照圈选的配置自动进行用户行为数据的采集和发送🚇。

优点:

  • 埋点代价小,更新代价小
  • 埋点只需业务同学接入,开发只需对接可视化SDK

缺点:

  • 无法做到自定义获取数据
  • 可视化埋点覆盖的功能有限
  • 仅支持客户端行为

无痕埋点

无痕埋点又叫全埋点🥪,网上又很多文章写的都是无痕埋点是将所有事件的操作全部上报😀,但是我们在实现的过程中肯定是不会监听那么多的事件吧😋,但是好像也有第三方服务商sdk集成了所有事件😏。

我的个人理解无痕埋点是针对某一个单一事件,在全局实现监听达到上报,而不是全部事件上报才叫无痕埋点🥙。只要有某个事件在全局实现监听,针对这个事件的埋点方式就称为无痕埋点🌯

优点:

  • 由于采集的是全量数据,所以产品迭代过程中是不需要关注埋点逻辑的,也不会出现漏埋、误埋等现象。
  • 无埋点方式因为收集的是全量数据,可以大大减少运营和产品的试错成本
  • 如果集成sdk之后无需埋点,方便快捷

缺点:

  • 缺点与可视化埋点相同,未解决个性化自定义获取数据的问题,缺乏数据获取的灵活性;
  • 数据量过大,如果不使用第三方服务商,针对自身的服务器是个考验

实现方案步骤(uni-app,其他项目逻辑相同)

两方面上报: 1.事件上报(目前只有点击事件埋点),2.停留时间上报

  • 事件上报:通过给元素绑定自定义指令的方式实现(减少对原有代码的侵入)🍜,将信息存储在缓存池中定时上报,上报之后清空之前的上报信息🥠。
  • 停留时间上报:需要重新封装路由,创建路由拦截在跳转之前记录来源,以及上一个页面的停留时间,当拦截器捕获成功之后🌯,如果发现停留时间大于xx秒进行上报🥙。

优点:清晰合理,比较适合新项目。

缺点:针对老项目需要与产品和运营对接埋点方案绑定自定义事件🤪,如果是老项目需要对uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab 进行二次封装。

问:为什么何将信息存储,而不是实时上报?
答:考虑到服务器的压力,采用了定时上报的方式。

问:为什么监听停留时长大于XX秒才进行上报?
答:1.服务器的压力问题。2考虑到用户可能做一些没意义的操作,所以停留时长大于XX秒才属于有效页面。

实现方法

事件埋点上报

  • common文件夹下创建自定义指令文件,在main.js中引用该文件。
import Vue from "vue";
// 自定义埋点指令
Vue.directive("buried", {bind: (el, binding) => {if (binding.value) {//这里参数是根据自己业务可以自己定义let params = {currentUrl: binding.value.currentUrl,triggerType: binding.value.triggerType,title: binding.value.title,frontTriggerType: binding.value.triggerType,behavior: binding.value.behavior,};//如果是浏览类型,直接保存,目前只考虑点击类型if (binding.value.triggerType == "browse") {console.log("browse", params);//调用后台接口保存数据} else if (binding.value.triggerType == "click") {//如果是click类型,监听click事件el.addEventListener("click",() => {// 将操作和内容存储在缓存中定时上报let buriedArray = uni.getStorageSync('buriedArray') //获取埋点集合buriedArray.push(params)  // 将埋点集合存入缓存中uni.setStorageSync('buriedArray', buriedArray)},false);}}},
});
复制代码

app.vue中的onLaunch生命周期中创建定时任务与缓存池,在onHide生命周期中销毁定时任务

let timeInterval = null
onLaunch(){uni.setStorageSync('buriedArray', [])// 定时上报埋点数据timeInterval = setInterval(() => {if (uni.getStorageSync('buriedArray').length > 0) {// 上报逻辑,根据需求自行完善upLoadBuriedInfo(uni.getStorageSync('buriedArray'))// 上报成功之后清空埋点数据重新上报uni.setStorageSync('buriedArray', [])}}, time)
}
onHide: function () {timeInterval && clearInterval(timeInterval)
}
复制代码

停留时间上报

  • 首先读取page.json中的文件获取pathtitle(原文链接),先在项目根目录创建一个router文件夹🍞,在vue.config.js里面加入如下代码,这样每次打包之后router文件夹下的index.js中就会生成一个 titlepath的对应表。😚
const path = require('path')
const fs = require('fs')const fromFile = path.join(__filename, '../pages.json')
const toFile = path.join(__filename, '../router/index.js')
const buffPrefix = Buffer.from('export default ')const fileData = fs.readFileSync(fromFile)// 转成可读的js, 正则删除注释, 不然JSON.parse会报错
const fileObj = JSON.parse(fileData.toString().replace(/\/\/.*/g, ''))// 遍历,只取路径和标题,其他的不要,已减小文件体积
const routes = fileObj.pages.map(e => {return {title: e.style ? e.style.navigationBarTitleText ? e.style.navigationBarTitleText : e.name : '未知',path: '/'+e.path,}
})
fs.writeFileSync(toFile, buffPrefix + Buffer.from(JSON.stringify(routes)))module.exports = {configureWebpack: {plugins: []}
}
复制代码
  • 在common中创建routeGuards.js 监听路由拦截,进行上报,在main.js中引用该文件
import Vue from 'vue';
import v5 from 'uuid/v5';
import UniRouteGuard from '@/js_sdk/pocky-route-gurads/lib';
import router from '@/router'
Vue.use(UniRouteGuard);const guard = new UniRouteGuard();let startTime = Date.now();
guard.beforeEach((to, from, next) => {let currentTime = Date.now();if (from.url && from.url == '/pages/first/index') {next()return}console.log(router)if (to.url) {if (to.url.indexOf('?') > -1) {to.url = to.url.substr(0, to.url.indexOf('?'))}}let fromName = router.find(item => item.path == from.url) ? router.find(item => item.path == from.url).title : '未知'let toName = router.find(item => item.path == to.url) ? router.find(item => item.path == to.url).title : '未知'const stayTime=  parseInt((currentTime - startTime) / 1000)const MY_NAMESPACE = '1b671a64-40d5-491e-99b0-da01ff1f3341';console.log(`由${fromName}跳转到${toName}并在${fromName}中停留了${stayTime}秒钟`);let params = {fromUrl: from.url, //来源地址toUrl: to.url, // 目的地址fromName: fromName, // 来源名称toName: toName, // 目的名称stayTime: stayTime, // 停留时长guid: v5(from.url, MY_NAMESPACE), //页面uuidappUuid: uni.getStorageSync('appUuid') ? uni.getStorageSync('appUuid') : '', // app唯一标识model: uni.getStorageSync("model")? uni.getStorageSync('model') : '', // 手机型号}console.log(params)if(stayTime>10){// 上报逻辑console.log('停留的时间大于10秒钟了,可以进行上报')}startTime = Date.now();next();
});
复制代码

因为uni-app 没有提供自身的路由拦截插件🥠,所以需要我们手动去封装🚘。这种方案针对新项目比较合适,但是针对老项目路由跳转的逻辑都已经通过原生的方式写完了😣,我们在进行封装的话修改的点太多了🤔,所以在网上找到了这个插件不用修改跳转api并且可以获取到上一个页面的路由(全局路由守卫),原文介绍的是通过npm的方式进行安装,我采用的是hbuilderX导入的方式(有需要的同学可以自行查找)🤙。

使用方法

  • 事件埋点:将需要埋点的元素绑定改指令v-buried绑定参数
<!-- 
triggerType: 事件类型
title: 页面标题
currentUrl: 页面路由
behavior: 操作行为
-->
<view v-buried="{
triggerType:'click',
title:'我的',
currentUrl: currentPath,
behavior:'点击我的收藏按钮'}">
</view>
复制代码

页面跳转

  • 需要在page.json中进行修改如果使用的是自定义导航条或者没有使用导航条需要进行命名
  • 需要将页面中跳转路径修改成绝对路径否则路由会匹配不到

uni-app集成友盟统计

  • 首先在友盟上创建一个应用获取其对应的appkey

  • 在uni-app的App模块配置中勾选友盟统计并填写对应的key(渠道id随意填写就可以)

  • 这样实际上就在uni-app中集成了友盟统计,如果想看到详细的上报数据可以在友盟后台进行查看(注:必须打包之后或者采用自定义基座的方式才能够进行上报,上报结果可能第二天才会生效,具体上报规则可以查看友盟官网解释)。

这样最基本的集成就完成了。

那我们如何埋入我们的自定义事件呢,比如我将一个燃气罩加入了购物车把他当成一个事件,并且能在友盟后台查看到我加入商品的属性以及加入空气炸锅或者加入电饼铛的一些数量对比

  • 1.在友盟后台注册相应的自定义事件 (我的应用->设置->添加事件)

  • 2.创建事件完毕之后在代码中进行上报的代码的编写(步骤一和步骤二谁先谁后都可以)
// https://www.html5plus.org/doc/zh_cn/statistic.html 文档链接
// 第一个参数: 在友盟后台注册的事件id,第二个参数:业务数据
plus.statistic.eventTrig("purchase", {"type":"book","quantity":"3"});
复制代码
  • 上报可能会有延迟,发行过一段时间之后就可以在友盟后台查看到相关数据。

  • 点击查看按钮可以看到更详细的数据,以及上报的业务数据对比

uni-app 自带统计

  • 无需集成其他相关sdk只需在manifest.json中勾选uni统计配置即可注:必须打包之后才能够进行上报,上报结果可能第二天才会生效,具体上报规则可以查看uni-app官网解释

  • 查看上报后台

  • uni统计也支持自定义埋点事件的上报
// 注意如果第一个参数是title第二个参数必须是字符串
uni.report("upload",{title: '上报数据',content: '上报内容'})
复制代码
  • 可在事件和转化模块中进行查看

在测试uni-app自带的统计中也遇到了一些问题,如果有朋友能够解决的话也可以帮助顶顶帖,我在进行完善问题贴。

总结

针对埋点的方案,自己也是不太熟悉,没有实战经验,找了很多途径,文中可能会有不对的地方,希望小伙伴们可以多多指点。一起加油!🤪


作者:drinkwd
链接:https://juejin.cn/post/7094146488439144455
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


http://chatgpt.dhexx.cn/article/qQRsJoVy.shtml

相关文章

前端组件化埋点方案与实现

背景 埋点&#xff0c;是收集产品的数据的一种方式&#xff0c;其目的是上报相关行为数据&#xff08;PV/UV/时长/曝光/点击等&#xff09;&#xff0c;由相关人员以此分析用户的使用习惯&#xff0c;助力产品不断迭代和优化。对于开发来说&#xff0c;通常不仅仅需要完成基础…

三分钟,教你3种前端埋点方式!

作者&#xff1a;彩虹修狗 https://juejin.cn/post/7224132741997281338 前言 只有了解用户&#xff0c;我们才能服务好用户&#xff0c;而最接近用户的我们&#xff0c;自然要承担起更多的责任。 那么在一个企业中&#xff0c;我们要如何去了解用户呢&#xff1f;最直接有效的…

前端数据埋点

数据埋点&#xff0c;是一种常用的数据采集方法。埋点是数据的来源&#xff0c;采集的数据可以帮助业务人员分析网站或者App的使用情况、用户行为习惯等&#xff0c;是后续建立用户画像、用户行为路径等数据产品的基础。 前端的埋点方式主要分为代码埋点、可视化埋点、无埋点三…

前端埋点实现

您好&#xff0c;如果喜欢我的文章&#xff0c;可以关注我的公众号「量子前端」&#xff0c;将不定期关注推送前端好文~ 前端埋点实践 介绍1. 实现自定义hook&#xff0c;监测组件2. 收集数据3.前端错误捕捉4. 发送后端保存数据5.收集数据展示总结 介绍 这段时间博主一直在投入…

前端埋点实现及原理分析

正如在宏观介绍的博客中写到的&#xff0c;做用户行为分析的方式有“前端埋点”和“后端埋点”的区分&#xff0c;真好今天敲了一个坤哥整理的“前端埋点”的程序&#xff0c;理解了之后结合demo来简单讲解“前端埋点”如何做。 前端埋点原理图&#xff1a; 如上所示&#xff…

FReLU

论文&#xff1a;https://arxiv.org/pdf/2007.11824.pdf 代码&#xff1a;https://github.com/megvii-model/FunnelAct 概述 卷积神经网络&#xff08;CNN&#xff09;在许多视觉识别任务&#xff08;例如图像分类&#xff0c;目标检测和语义分割&#xff09;中均达到了最先进…

LFR benchmark在windows操作系统下形成网络详细步骤

研究社交网络的人应该都知道LFR benchmark network吧。但是我从网上找到很多关于LFR的压缩包&#xff0c;里面包含很多.cpp文件&#xff0c;在vs下建工程&#xff0c;把这些文件放进去却怎么也跑不通&#xff0c;真的是很恼火。 今天&#xff0c;终于看到一篇博客&#xff0c;…

神经网络-LFR model

CLDNN[1] 不同的网络结构有不同的优势 CNN擅长减少频率偏移LSTM擅长对时序信号进行建模DNN可以对特征做更高阶的抽象&#xff0c;更容易进行分类 CLDNN依次将CNN/LSTM/DNN进行串联组合成一个新的网络&#xff0c;相当于依次进行频域变化/时域关联/特征抽象&#xff0c;相比于…

CRLF和LF区别

目录&#xff1a; 文章目录 1、什么是CRLF和LF2、为什么要探究CRLF和LF3、三种方式处理的不同4、在Git中如何转换&#xff1f;参考文献 1、什么是CRLF和LF CRLF 是carriagereturnline feed的缩写。中文意思是回车换行。 LF是line feed的缩写&#xff0c;中文意思是换行。 2、…

LFR benchmark 操作步骤

先奉上资源 链接&#xff1a;https://pan.baidu.com/s/1Mm_UwUAhM0ofKXcFbti0YA 提取码&#xff1a;hvp8 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦运行操作 在解压后的文件下找到 /benchmark/Debug 文件夹&#xff0c; 在该文件下运行命令行程序&#x…

西克推出LBR/LFR长距离非接触物位/液位传感器

西克推出LBR/LFR长距离非接触物位/液位传感器 在日常的生产过程中&#xff0c;我们可能会遇到一些严苛的工作环境&#xff0c;例如上百米高的筒仓&#xff0c;诸多粉尘的罐内环境&#xff0c;亦或是充满蒸汽或附着物的生产环境&#xff1b;对料位的监控显得更加重要和困难。传…

CRLF和LF

目录&#xff1a; 什么是CRLF和LF为什么要探究CRLF和LF三种方式处理的不同更多参考文献 &#x1f441; 关注微信公众号&#xff1a;非典型理科男 回复&#xff1a;架构设计 获取 架构设计经典著作 1、什么是CRLF和LF CRLF 是carriagereturnline feed的缩写。中文意思是回车换…

使用Arduino Uno构建一个巡线机器人

使用Arduino Uno构建一个巡线机器人 原文 MX 巡线机器人&#xff08;LFR: line follower robot&#xff09;是一种简单的自主引导机器人&#xff0c;它遵循在地面上绘制的线来检测白色表面上的暗线或黑暗表面上的白线。在本教程中&#xff0c;使用 Arduino Uno 和一些易于访问…

网络科学—Windows下生成LFR人工网络数据集的步骤

目录 1 引言 2 步骤 2.1 下载LFR程序包 2.2 解压LFR程序包 2.3 进入cmd程序 2.4 生成LFR网络 1 引言 很多做网络科学研究的学者研究生等都需要经常用到人工网络的数据&#xff0c;最为常用的就是LFR人工网络&#xff0c;下面详细描述了LFR网络的生成方式 2 步骤 2.1 下…

查看gcc编译器版本

我们在windows下DS5中编译时使用GCC交叉编译器&#xff0c;但是在ubuntu时也需要使用GCC编译器&#xff0c;这时最好时保持版本一致&#xff0c;所以就需要查看windows下版本&#xff0c;如下图&#xff0c;在按装的文件夹中找到对应得文件即可。 转载于:https://www.cnblogs.c…

linux下gcc版本切换

今天在linux环境下编译c文件的时候发现库函数居然找不到路径&#xff0c;查了好久都没有找到是什么问题&#xff0c;最后想到的解决办法&#xff1a;把gcc版本切回到linux自带版本 1.查看linux下已安装gcc版本 ls /usr/bin/gcc* 结果如下&#xff1a; 2.手动设置候选版本优先…

linux中gcc版本升级

环境 Linux version 3.10.0-1160.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) ) #1 SMP Mon Oct 19 16:18:59 UTC 2020 目前gcc版本4.8.5 正文 所需资源可以在gnu安装包下载_开源镜像站-阿里云下载 包括&#x…

Linux升级gcc到最新版本--gcc-9.1.0

Linux升级gcc到最新版本–gcc-9.1.0详细步骤 一、下载gcc最新的源码包–>wget http://ftp.gnu.org/gnu/gcc/gcc-9.1.0/gcc-9.1.0.tar.gz 二、解压缩–>tar -xzvf gcc-9.1.0.tar.gz 三、进入解压缩后目录–>cd gcc-9.1.0 四、运行download_prerequisites脚本&#xff0…

所有Gcc版本对C和C++的支持情况(超详细版本)

在最近接触的新的项目&#xff0c;由于技术使用为C98风格实现&#xff0c;遇到一个问题需要加锁解决&#xff0c;本能反应用lock_guradmutex解决&#xff0c;但是没设置CFLAGS为C11标准&#xff0c;不确定当前gcc编译器默认支持的C和C标准是什么&#xff0c;索性就一把都研究透…