前端埋点实现

article/2025/10/8 8:41:51

您好,如果喜欢我的文章,可以关注我的公众号「量子前端」,将不定期关注推送前端好文~

前端埋点实践

    • 介绍
    • 1. 实现自定义hook,监测组件
    • 2. 收集数据
    • 3.前端错误捕捉
    • 4. 发送后端保存数据
    • 5.收集数据展示
    • 总结

介绍

这段时间博主一直在投入组件库的开发工作,最初其实就是想提供一套组件库来使用并且开源,和大家一起学习,最近突然有一个思路,可以从组件库文档页拉取一下用户的数据,来对组件库更好的维护。

组件库的链接在这里

主要思路还是采用的代码埋点,在每个组件的页面挂载的时候注入埋点,进行数据收集、最后提交给后端来进行长保存。

1. 实现自定义hook,监测组件

代码如下:

import { useEffect, useRef } from 'react';
import getUserIp from '../track/getUserIp';
import getNativeBrowserInfo from '../track/getNativeBrowserInfo';
import sendData from '../track/sendData';const usePageListener = (componentName: string) => {//监测单组件文档页面停留时间,进行埋点const leaveTime = useRef<number>(0);const timer = useRef<any>();useEffect(() => {//计算页面停留时间timer.current = setInterval(() => {leaveTime.current = leaveTime.current + 1;}, 1000);return () => {clearInterval(timer.current);};}, [leaveTime]);useEffect((): any => {return async () => {//组件销毁,如果停留时间大于十秒,发送单组件埋点记录console.log('销毁', componentName, leaveTime.current);let trackInfo = {componentName,leaveTime: leaveTime.current,};const userDeviceInfo = (await getUserIp()) as object; //用户个人相关信息const nativeBrowserInfo = (await getNativeBrowserInfo()) as object; //浏览器原生的信息trackInfo = { ...trackInfo, ...userDeviceInfo, ...nativeBrowserInfo };//将收集到的数据发送给后端const result = await sendData(trackInfo);return result;};}, []);
};export default usePageListener;

usePageListener hook主要有两个阶段:

  1. 组件挂载阶段,进行页面时间监听,计时用户在该页面停留了多少秒。
  2. 组件销毁阶段,停止计时,并开始收集数据,最后发送给后端。

2. 收集数据

我这里主要收集了两类数据,个人相关信息的收集函数getUserIp如下:

const getUserIp = () => {return new Promise((resolve, reject) => {const scriptElement = document.createElement('script');scriptElement.src = `http://pv.sohu.com/cityjson?ie=utf-8`;document.body.appendChild(scriptElement);scriptElement.onload = () => {try {document.body.removeChild(scriptElement);resolve(returnCitySN);} catch (e) {reject(e);}};});
};export default getUserIp;

这里是借助了搜狐的第三方接口来获取用户的IP地址和所在城市。

浏览器原生的数据方法getNativeBrowserInfo如下:

import { getNowTime } from '../getNowTime';type nativeBrowserInfoType = {domain?: string;url?: string;title?: string;referrer?: string;screenHeight?: number | string;screenWidth?: number | string;color?: number;lang?: string;ua?: string;watchTime?: string;memory?: string;connectTime?: string;responseTime?: string;renderTime?: string;
};
const formatMemory = (val: number) => {//格式化内存数据return Math.floor(val / 1024 / 1024) + 'mb';
};
const formatTimeToSecord = (val: number) => {//转换为秒return val / 1000 + 's';
};
const getNativeBrowserInfo = () => {//获取浏览器原生数据return new Promise((resolve) => {const params: nativeBrowserInfoType = {};if (document) {params.domain = document.domain || ''; //获取域名// params.url = String(document.URL) || ''; //当前Url地址params.title = document.title || '';// params.referrer = String(document.referrer) || ''; //上一跳路径}//Window对象数据if (window && window.screen) {params.screenHeight = window.screen.height || 0; //获取显示屏信息params.screenWidth = window.screen.width || 0;params.color = window.screen.colorDepth || 0;}//navigator对象数据if (navigator) {params.lang = navigator.language || ''; //获取所用语言种类params.ua = navigator.userAgent.toLowerCase(); //运行环境}//获取性能相关参数if (window && window.performance) {params.memory = formatMemory(window.performance.memory.usedJSHeapSize);params.connectTime = formatTimeToSecord(window.performance.timing.connectEnd - window.performance.timing.connectStart,);params.responseTime = formatTimeToSecord(window.performance.timing.responseEnd - window.performance.timing.responseStart,);params.renderTime = formatTimeToSecord(window.performance.timing.domComplete - window.performance.timing.domLoading,);}params.watchTime = getNowTime();resolve(params);});
};export default getNativeBrowserInfo;

这里是收集了设备、运行环境以及页面加载内存性能相关的数据,也是可以知道h5在每个设备中是否有不一样的加载表现,从而进行针对性优化。

最终收集到的数据样例是这样的:
在这里插入图片描述

3.前端错误捕捉

通过window.onerror方法,捕捉到前端出现的错误信息,并上报给后端,主要是实现代码如下:

import { getNowTime } from '../getNowTime';type errorList<T> = {errorMessage?: T;scriptURI?: T;errorObj?: T;happenURI?: T;happenTime?: T;
};
const getErrorInfo = () => {const errorList: errorList<string | Event | number | undefined> = {};window.onerror = (errorMessage, scriptURI, errorObj) => {errorList.errorMessage = errorMessage;errorList.scriptURI = scriptURI;errorList.happenURI = window.location.href.replace('#', '');errorList.errorObj = errorObj;errorList.happenTime = getNowTime();const sendScript = document.createElement('script');const requestAddress = `http://react-view-ui.com:9999/saveErrorMessage?info=${JSON.stringify(errorList,)}`;sendScript.src = requestAddress;document.body.appendChild(sendScript);};
};export { getErrorInfo };

这里主要收集了报错信息、报错的页面地址、报错时间等参数,这里我们就可以自己去mock出错误。

4. 发送后端保存数据

数据收集完毕,准备发送给后端,这里是加入了一个script脚本,请求后端,并把收集到的数据传给后端,代码如下:

const sendData = (params: object) => {const sendScript = document.createElement('script');const requestAddress =process.env.NODE_ENV === 'development'? `http://localhost:9999/saveComponentLog?info=${JSON.stringify(params)}`: `http://react-view-ui.com:9999/saveComponentLog?info=${JSON.stringify(params)}`;sendScript.src = requestAddress;sendScript.async = true;document.body.appendChild(sendScript);return new Promise((resolve, reject) => {sendScript.onload = () => {try {document.body.removeChild(sendScript);resolve('');} catch (e) {reject(e);}};});
};
export default sendData;

至此…埋点就做完了,线上服务器也可以实时获取到用户的数据,保存在数据库中,提供给我进行参考了~哈哈哈

在这里插入图片描述

5.收集数据展示

这里一共有两张表,用户信息表和错误表。

用户信息表:

在这里插入图片描述

错误表:

在这里插入图片描述

总结

最后…留一下React-View-UI的链接~~

Concis组件库线上链接:http://react-view-ui.com:92
github:https://github.com/fengxinhhh/Concis
npm:https://www.npmjs.com/package/concis

开源不易,欢迎学习和体验,喜欢请多多支持,有问题请留言。


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

相关文章

前端埋点实现及原理分析

正如在宏观介绍的博客中写到的&#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;索性就一把都研究透…

Linux 安装指定版本GCC方法

今天来记录一下如何安装指定版本gcc&#xff0c;因为在linux中有些软件需要指定gcc的版本&#xff0c;所以记录一下还是很有必要的。好了&#xff0c;直接上安装步骤。 第一步&#xff1a;安装默认版本gcc 首先我们需要安装一个gcc&#xff0c;我们使用yum命令来进行安装。 $ y…

linux升级gcc版本详细教程

0.前言 一般linux操作系统默认的gcc版本都比较低&#xff0c;例如centos7系统默认的gcc版本为4.8.5。gcc是从4.7版本开始支持C11的&#xff0c;4.8版本对C11新特性的编译支持还不够完善&#xff0c;因此如果需要更好的体验C11以及以上版本的新特性&#xff0c;需要升级gcc到一个…

ubuntu20.04查看gcc版本以及各版本切换

1、查看自己当前的gcc版本 gcc -v通过下图的最后一行可以得到&#xff0c;这里电脑当前gcc的版本是 7.5.0 查看Eigen版本&#xff1a; pkg-config --modversion eigen32.安装另一个版本gcc 这里安装的是gcc-9&#xff1a; sudo add-apt-repository ppa:ubuntu-toolchain-r…

最新:斐讯K3千兆无线路由器刷官改版固件的详细图文教程

2018年1月31日更新&#xff1a;本教程已经同步增添Phitools 作者最新修改的固件以便支持 K3_V21.6.12.66 版刷机。 如果喜欢折腾的话可以刷LEDE固件&#xff0c;刷机方法看&#xff1a;[图文教程] 斐讯K3金/银色版路由器免拆机通用刷机教程 此前蓝点网已经发布了借助恩山论坛开…