前端埋点方式
前言:
想要了解用户在系统中所做的操作,从而得出用户在本系统中最常用的模块、在系统中停留的时间。对于了解用户的行为、分析用户的需求有很大的帮助,想实现这种需求可以通过前端埋点的方式。
埋点方式:
1.什么是埋点?
“埋点”是一种在应用程序或网站中插入代码的方式,用于收集用户行为或特定事件(点击事件、浏览时间、搜索事件等)的信息。它是用于分析和监控用户行为、应用性能和其他指标的一种方法。
2.埋点的目的
为了收集关键的数据和指标,以便帮助了解用户的行为、改进用户的体验、·优化应用性能、支持业务决策
3.埋点收集的数据类型
(1)用户行为类型:例如:页面浏览量、点击事件、表单提交、购买行为等
(2)应用性能数据:例如:页面加载时间、API调用延迟、错误日志等
(3)设备和环境数据:例如:用户设备类型、操作系统、浏览器版本等
(4)用户属性数据:例如:用户ID、地理位置、用户角色等
4.常见的埋点方式
(1)手动埋点:开发人员在代码中显示的插入埋点代码,通常使用Javascript或其他编程语言实现。(比较常用的方法)
(2)自动埋点:使用自动化工具或框架,自动收集 某些标准事件或用户行为数据
(3)可视化埋点:使用可视化工具,在页面上直接选择元素或交互,并配置要捕获的事件
5.常用埋点方法实例
(1)基于ajax的埋点上报
因为埋点实际上是对关键节点的数据进行上报和服务端交互的一个过程,所以我们可以和后端约定一个接口通过ajax进行数据上报。
代码如下:
function buryingPointAjax(data) {return new Promise((resolve, reject) => {// 创建ajax请求const xhr = new XMLHttpRequest()// 定义请求接口xhr.open("post", '/buryingPoint', true)// 发送数据xhr.send(data)})
}// 使用
let info = {}
buryingPointAjax(info) // 这样就成功上报了info的对象
缺点:
一般而言,埋点域名并不是当前域名,因此请求会存在跨域风险,且如何ajax配置不正确可能会被浏览器拦截。因此使用ajax请求并不是万全之策
(2)基于img的埋点上报
数据上报前端主要是负责将数据传递到后端,并不过分强调前后端交互,因此可以通过一些支持跨域的标签去实现数据上报功能。script、link、img就是我们上报的数据最好对象,推荐使用img标签去实现。如果需要请求script和link,我们需要将标签挂载到页面上,会反复操作dom造成页面性能受影响,而且载入js/css资源还会阻塞页面渲染,影响用户体验,所以选择使用script和link进行埋点的话要慎重考虑。而img标签并不需要挂载到页面上,基于js去new image(),设置src后就可以直接请求图片。
代码如下:
// 控制台创建一个image标签
var img = new image()
img.src="https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web/img/MaskGroup.13dfc4f1.png"
可以看到即使未被挂载到页面上依旧发起了请求

// 创建script标签
let a = document.createElement('script')
a.src = 'https://lf-headquarters-speed.yhgfb-cn-static.com/obj/rc-client-security/web/stable/1.0.0.28/bdms.js'
创建一个script标签,未挂载到页面上,并不会发起请求

// 将标签挂载到页面上
document.body.appendChild(a)
这个时候就可以看到发起请求了

(3)基于Navigator.sendBeacon的埋点上报
Navigator.sendBeacon是目前通用的埋点上报方案。Navigator.sendBeacon方法接受两个参数,第一个参数是目标服务器的URL,第二个参数是所要发送的数据(可选),可以是任意类型(字符串、表单对象、二进制对象等等)。
navigator.sendBeacon()方法可用于通过HTTP POST将少量数据异步传输到Web服务器。它主要用于将统计数据发送到Web服务器,同时避免了用传统技术(XMLHttpRequest)发送分析数据的一些问题。
注:sendBeacon如果成功进入浏览器的发送队列后,会返回true;如果受到队列总数、数据大小的限制后,会返回false。返回ture后,只是表示进入了发送队列,浏览器会尽力保证发送成功,但是否成功,不会再有任何返回值。
例子:

发送了一个post请求,将小量的数据发送到服务端,用于统计数据

相较于img标签,使用navigator.sendBeacon会更规范,数据传输上可传输资源类型会更多。
对于ajax在页面卸载时上报,ajax有可能没上报完,页面就卸载了导致请求中断,因此ajax处理这种情况时必须作为同步操作。
sendBeacon是异步的,不会影响当前页到下一个页面的跳转速度,且不受同域限制。这个方法还是异步发出请求,但是请求和当前页面脱离关联,作为浏览器的任务,因此可以保证会把数据发出去,不拖延卸载流程。
结论
1.img兼容性好
2.无需挂载到页面上,反复操作DOM
3.img的加载不会阻塞html的解析,但img加载后并不渲染,它需要等待Render Tree生成完之后才和Render Tree一起渲染出来
4.通常埋点上报会使用gif图,合法的GIF只需要43字节
5.不推荐ajax
6.考虑兼容性的话,img是不二之选
7.最适合的方案是Navigator.sendBeacon
6.常见的埋点行为
点击触发埋点
// 绑定点击事假,当点击目标元素时,触发埋点上报
function clickButton(url, data) {navigator.sendBeacon(url, data)
}
页面停留时间上报埋点
// 路由文件中,初始化一个startTime,当页面离开时通过路由守卫计算停留时间
let url = ''// 上报地址
let startTime = Date.now()
let currentTime = ''
router.beforeEach((to, from, next) => { if (to) {currentTime = Date.now()stayTime = parseInt(currentTime - startTime)navigator.sendBeacon(url, {time: stayTime})startTime = Date.now()}})
错误监听埋点
// 通过监听函数去接收错误信息
// vue错误捕获
app.config.errorHandler = (err) => {
navigator.sendBeacon(url, {error: error.message, text:'vue运行异常'})// JS异常与静态资源加载异常
window.addEventListener('error', (error) => {if(error.message) {navigator.sendBeacon(url, {error: error.message, text:'js执行异常'})} else {navigator.sendBeacon(url, {error: error.filename, text: '资源加载异常'})}
})// 请求错误捕获
axios.interceptors.response.use((response) => {if(response.code === 200) {return Pormise.resolve(response)} else {return Promise.reject(response)}},(error) => {// 返回错误逻辑navigator.sendBeacon(url, {error: error, text: '请求错误异常'})}
)
内容可见埋点
// 通过交叉观察器去监听当前元素是否出现在页面// 可见性发生变化后的回调
function callback(data) {navigator.sendBeacon(url, {target: data[0].target, text: '内容可见'})
}
// 交叉观察器配置项
let options = {}
// 生成交叉观察器
const observer = new IntersectionObserver(callback)
// 获取目标节点
let target = document.getElementById("target")
// 监听目标元素
observer.observe(target)
其他更详细埋点内容可参考:https://mp.weixin.qq.com/s/lQos8C9y_6-ZT886k3aR9g
相关文章:
前端埋点方式
前言: 想要了解用户在系统中所做的操作,从而得出用户在本系统中最常用的模块、在系统中停留的时间。对于了解用户的行为、分析用户的需求有很大的帮助,想实现这种需求可以通过前端埋点的方式。 埋点方式: 1.什么是埋点?…...
iOS导航栏返回按钮
导航栏返回按钮隐藏: override func pushViewController(_ viewController: UIViewController, animated: Bool) {if let vc self.viewControllers.last {let backItem UIBarButtonItem()backItem.title ""vc.navigationItem.backBarButtonItem backI…...
2023中国视频云市场报告:腾讯云音视频解决方案份额连续六次蝉联榜首,加速全球化布局
近日,国际数据公司(IDC)发布了《中国视频云市场跟踪(2023上半年)》报告,腾讯云音视频的解决方案份额连续六次蝉联榜首,并在视频生产创作与媒资管理市场份额中排名第一。同时,在实时音…...
jpa Repository的常用写法总结
一、前言 之前项目在xml中写sql,感觉标签有很多,比较灵活; 最近在写新项目,使用了jpa,只能在java中写sql了,感觉不太灵活,但是也得凑付用。 以下总结下常用入参出参写法。 二、Repository代…...
笔记本电脑 禁用/启用 自带键盘
现在无论办公还是生活 很多人都会选择笔记本电脑 但很多人喜欢机械键盘 或者 用一些外接键盘 但是很多时候我们想操作 会碰到笔记本原来的键盘导致错误操作 那么 我们就需要将笔记本原来的键盘禁用掉 我们先以管理员身份运行命令窗口 然后 有两个命令 禁用默认键盘 sc conf…...
基于 golang 从零到一实现时间轮算法 (三)
引言 本文参考小徐先生的相关博客整理,项目地址为: https://github.com/xiaoxuxiansheng/timewheel/blob/main/redis_time_wheel.go。主要是完善流程以及记录个人学习笔记。 分布式版实现 本章我们讨论一下,如何基于 redis 实现分布式版本的…...
k8s 1.28安装
容器运行时,containerd 按照官方的指导,需要安装runc和cni插件,提示的安装方式,有三种: 二进制安装包源码apt-get 或 dnf安装 我们这里选用第三种,找到docker官方提供的安装方式 ubuntu-containerd # A…...
安装anaconda时控制台conda-version报错
今天根据站内的一篇博客教程博客在此安装anaconda时,检查conda版本时报错如下: >>>>>>>>>>>> ERROR REPORT <<<<<<<<<<<< Traceback (most recent call last): File “D:\An…...
链表(1)
目录 单链表 主函数test.c test1 test2 test3 test4 头文件&函数声明SList.h 函数实现SList.c 打印SLPrint 创建节点CreateNode 尾插SLPushBack 头插SLPushFront 头删SLPopBck 尾删SLPopFront 易错点 本篇开始链表学习。今天主要是单链表&OJ题目。 单链…...
智慧农业:农林牧数据可视化监控平台
数字农业是一种现代农业方式,它将信息作为农业生产的重要元素,并利用现代信息技术进行农业生产过程的实时可视化、数字化设计和信息化管理。能将信息技术与农业生产的各个环节有机融合,对于改造传统农业和改变农业生产方式具有重要意义。 图扑…...
知识注入以对抗大型语言模型(LLM)的幻觉11.6
知识注入以对抗大型语言模型(LLM)的幻觉 摘要1 引言2 问题设置和实验2.1 幻觉2.2 生成响应质量 3 结果和讨论3.1 幻觉3.2 生成响应质量 4 结论和未来工作 摘要 大型语言模型(LLM)内容生成的一个缺点是产生幻觉,即在输…...
机器人物理交互场景及应用的实际意义
机器人物理交互场景是指机器人与物理世界或人类进行实际的物理互动和交互的情境。这些场景涉及机器人在不同环境和应用中使用其物理能力,以执行任务、提供服务或与人类互动。 医疗协助: 外科手术助手:机器人可以用于外科手术,提供…...
Kubernetes Dashboard 用户名密码方式登录
Author:rab 前言 为了 K8s 集群安全,默认情况下 Dashboard 以 Token 的形式登录的,那如果我们想以用户名/密码的方式登录该怎么操作呢?其实只需要我们创建用户并进行 ClusterRoleBinding 绑定即可,接下来是具体的操作…...
Redisson中的对象
Redisson - 是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, …...
GNU ld链接器 lang_process()(二)
一、ldemul_create_output_section_statements() 位于lang_process()中11行 。 该函数用于创建与目标有关的输出段的语句。这些语句将用于描述输出段的属性和分配。 void ldemul_create_output_section_statements (void) {if (ld_emulation->create_output_section_sta…...
《国产服务器操作系统发展报告(2023)》重磅发布
11月1日,《国产服务器操作系统发展报告(2023)》(以下简称“报告”)在 2023 云栖大会上正式发布,开放原子开源基金会理事长孙文龙、中国信息通信研究院副总工程师石友康、阿里云基础软件部副总裁马涛、浪潮信…...
【PTE-day03 报错注入】
报错注入 1、报错注入 group by count2、报错注入 extractvalue3、报错注入updatexml1、报错注入 group by count http://124.222.124.9:8888/Less-5/?id=-1 union select 1,count(*),concat((select database()),ceil(rand(0)*2)) as a from information_schema.tables grou…...
jenkins gitlab CI/CD
jenkins的安装教程就不说了:Jenkins docker 一键发布 (一)_jenkins 一键发布-CSDN博客 最近打算从svn切换到gitlab,所以配置了一下jenkins的git 很简单,直接上图 1 选择 Git 2 录入gitlab的http地址(由于我的git地址不是22端口&…...
Java 中的数据类型有哪些?
Java中主要有八种基本数据类型: 1、整型:byte、short、int、long 2、字符型:char 3、浮点型:float、double 4、布尔型:boolean 一、整型 Java中整型数据属于有符号数,即第一个bit位为0表示正整数&…...
基于SSM的大学学生成长系统
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
