首页/文章/前端监控

前端埋点重要环节:前端如何录制用户的操作过程

2023-12-19
16716 分钟
...

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

背景

公司有很多的项目,但是并不是每一个项目都很重要,其实重要的项目就那么几个,上面也是很重视这几个项目,尤其是对一些生产问题的关注度很高。

这几天上面交代下来了,需要对这些项目做一些用户行为的记录,主要是为了更好地还原用户在某一个时间点的操作过程

注意点

想要完成这个需求,仔细想了一下,需要注意几个点:

  • 跨框架使用: 这些项目有vue、angular、react,需要都能适用
  • 能录制用户行为: 能把用户在页面上的操作录制下来
  • 能回放录制: 如果不能回放,那么这个录制就无意义了
  • 用户无感知: 必须做到用户无感知才行

思考 & 技术方案

说到前端视频的录制,我们会想到 webRTC 这个技术,他能做到录制屏幕的效果,但是通过 webRTC 去完成这个方案的话,有几个缺点:

  • 做不到用户无感知,需要用户同意才能录制
  • 录制的视频太大了,太占内存了
  • 学习成本比较高,这也是原因之一

那怎么才能做到:

  • 用户无感知
  • 不录制视频

其实只要不录制视频了,那么用户肯定就无感知,因为一旦要录视频,浏览器肯定要询问用户同意不同意。

所以我们选择了另一个方案 rrweb,一个用来录制用户页面行为的库~

rrweb

rrwebrecord and replay the web 的简写,旨在利用现代浏览器所提供的强大 API 录制并回放任意 web 界面中的用户操作。

效果展示

基本使用

我们先定义好 html 结构,三个按钮

  • 录制:点击开始录制
  • 回放:点击开始回放
  • 返回:点击重新再来

还有一个 replayer ,用来当做回放的容器

<template>
  <div class="main">
    <div >
      <el-button @click="record">录制</el-button>
      <el-button @click="replay">回放</el-button>
      <el-button @click="reset">返回</el-button>
    </div>
    <div v-if="!showReplay">
      <div>
        <el-input style="width: 300px" v-model="value" />
      </div>
      <div>
        <el-button>按钮1</el-button>
      </div>
      <div>
        <el-button>按钮2</el-button>
      </div>
      <div>
        <el-button>按钮3</el-button>
      </div>
    </div>
    <div ref="replayer"></div>
  </div>
</template>

我们需要先安装两个包:npm i rrweb rrwebPlayer

  • **rrweb:**用来录制网页的
  • **rrwebPlayer:**用来回放的

rrweb拥有一个 record 函数来进行录制操作,并可传入配置,emit属性就是用户操作的监听函数,接收一个参数event,这个参数是什么,我们后面会说~

然后我们定义三个函数:

  • record:录制函数
  • replay:回放函数
  • reset:返回/重置函数
const rrweb = require("rrweb");
import rrwebPlayer from "rrweb-player";

const events = ref([]);
const stopFn = ref(null);
const showReplay = ref(false);
const replayer = ref(null)

const record = () => {
  console.log("开始录制");
  stopFn.value = rrweb.record({
    emit: (event) => {
      events.value.push(event);
    },
    
    recordCanvas: true,
    collectFonts: true,
  });
};
const replay = () => {
  stopFn.value();
  showReplay.value = true;
  new rrwebPlayer({
    
    target: replayer.value,
    
    props: {
      
      events: events.value,
    },
  });
};
const reset = () => {
  showReplay.value = false;
  events.value = []
};

录的是视频吗?

我们之前说了:一旦要录视频,浏览器肯定要询问用户同意不同意。但是我们发现我们使用 rrweb 去录制,浏览器并没有询问,做到了无感知~所以我们可以推断出,rrweb 录制的并不是视频,那录制的是什么呢?

我们其实可以试着去输出一下刚刚的参数 event 看看是什么

rrweb.record({
    emit: (event) => {
        
+      console.log(event)
      events.value.push(event);
    },
});

我们可以看到这个event记录的东西是当前页面的DOM结构,当用户操作页面时,rrweb会将每一次的DOM结构转换成对象形式,通过 emit 函数的第一个参数输出,我们使用一个数组去记录这一次次的DOM结构,然后把它传给rrweb-player,它能将这些DOM结构按照先后顺序,一个一个展示出来,自然就相当于是视频的展示效果了~

rrweb能记录这些页面的 DOM 行为:

  • 节点创建、销毁
  • 节点属性变化
  • 文本变化
  • 鼠标移动
  • 鼠标交互
  • 页面或元素滚动
  • 视窗大小改变
  • 输入

上传 & 优化

我们记录的这些数据,需要上传到后端那边去,方便后续在后台管理系统里管理这些回放~

很多人会说这样一直录制,那岂不是数据量很大?所以我觉得只有在一些重要的页面,才需要做录制行为的操作,而不是每一个页面都去做这样的操作~

并且每次上传需要一定的时间间隔,不能上传太频繁,不然浏览器压力会增大~

const record = () => {
  console.log("开始录制");
  stopFn.value = rrweb.record({
    emit: (event) => {
      events.value.push(event);
    },
    recordCanvas: true,
    collectFonts: true,
  });
};

const report = async () => {
  await reportRequest(events.value);
  events.value = [];
}


setInterval(report, 10 * 2000);

同时,虽然现在上传的是DOM结构的对象,大小远远比视频小,但是其实还是不小的

所以我们需要采取措施,去压缩一下数据,压缩后再进行上传,这样能降低服务器的压力~我们可以使用packFn属性来对录制的数据进行压缩,同时回放时也要用unpackFn去解码

const record = () => {
  console.log("开始录制");
  stopFn.value = rrweb.record({
    emit: (event) => {
      events.value.push(event);
    },
    recordCanvas: true,
    collectFonts: true,
+    packFn: rrweb.pack
  });
};

const replay = () => {
  stopFn.value();
  showReplay.value = true;
  new rrwebPlayer({
    
    target: replayer.value,
    
    props: {
      
      events: events.value,
+      unpackFn: rrweb.unpack,
    },
  });
};

结语 & 加学习群 & 摸鱼群

我是林三心

  • 一个待过小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司的作死型前端选手;
  • 一个偏前端的全干工程师;
  • 一个不正经的掘金作者;
  • 一个逗比的B站up主;
  • 一个不帅的小红书博主;
  • 一个喜欢打铁的篮球菜鸟;
  • 一个喜欢历史的乏味少年;
  • 一个喜欢rap的五音不全弱鸡

如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 --> 摸鱼沸点

如果您觉得这篇文章有帮助,请点个赞吧~

分享文章

相关文章

更多文章 →
前端监控2025-05-29
前端错误收集方式
在讲错误收集方式之前,先理清一下前端编码时有那些常见错误 &nbsp; &nbsp; &nbsp; &nbsp; 前端错误收集是保障用户体验、排查线上问题的关键手段。本文将从多个角度详解前端错误收集的各种方式,包括不同框架(如 React、Vue)、JavaScript 执行环境中的同步/异步/Promise 错误、资源加载错误(如图片、script 加载失败)等。以下是全面的错误捕获机制总结: &nbsp; &nbsp; 🌐 一、通...
学习
前端监控2024-10-12
前端小玩具~错误捕获定位工具
正文 我们在平时的工作中,开发功能的同时不可能把场景考虑的面面俱到,而生产环境往往情况是非常复杂的,用户录入进去的数据总是千奇百怪,那如果遇到问题的话,我们又要如何进行排查呢?总不可能让用户录个屏吧哈哈 所以我们就出现了 前端埋点 的操作,不过埋点的方向以及文章都挺多的,也都挺复杂的,这篇文章我们就讲一个比较有趣的 错误捕获思路 。 我们平时在使用框架开发 遇到bug 时,比如 Vue ,如果是在本地环境,我们在控制台可以很容易的找到出...
学习
前端监控2024-09-19
🍻 前端服务监控原理与手写开源监控框架SDK前端服务监控概述
前端监控的目的很明确,无非就是让我们的产品更完善,更符合我们和用户的需求。运营与产品团队需要关注用户在产品内的行为记录,通过用户的行为记录来优化产品,研发与测试团队则需要关注产品的性能以及异常,确保产品的性能体验以及安全迭代。 而一个完整的前端监控平台至少需要包括三个部分: 数据采集与上报、数据整理和存储、数据展示 。算上需要监控的项目的话,也就是说,至少需要4个项目才能完整的记录前端监控的内容。 下图是一个完整的前端监控平台需要处理和...
学习
前端监控2024-08-19
前端数据监控平台
比如客户说:你们的页面咋白屏了? 开发:具体可以给我说一下,白屏之前你做了什么吗? 客户:我就点了一下按钮 开发:你能告诉我是哪个页面的哪个按钮吗? 最后,客户极其不耐烦的地丢过来一张没有缺少url的白屏给你看,试图证明他说的是真的,真白屏了。 最后不再理睬你! 开发人员试图找到解决方案,想快速解决线上bug,但是客户却以为你在质疑他。 真的有点秀才遇上兵有理说不清,其实真的没有谁对谁错,只是双方立场不同,作为客户,你的系统bug了,我...
学习
前端监控2024-02-20
前端实现埋点&监控
实现埋点功能的意义主要体现在以下几个方面: 0. 数据采集:埋点是数据采集领域(尤其是用户行为数据采集领域)的术语,它针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。通过埋点,可以收集到用户在应用中的所有行为数据,例如页面浏览、按钮点击、表单提交等。 1. 数据分析:采集的数据可以帮助业务人员分析网站或者App的使用情况、用户行为习惯等,是后续建立用户画像、用户行为路径等数据产品的基础。通过数据分析,企业可以更好地了解...
学习
前端监控2023-11-23
Web性能监测的利器Performance Observer
前言 前段时间在研究前端异常监控平台,在思考性能监控时,想到了浏览器自带的观察者以及页面生命周期API 。于是在翻查资料时发现了, API。正好趁着这个机会给大家好好讲讲Performance Observer API Performance Observer(性能观察者) 定义 是一种JavaScript API,用于监测页面性能指标,如资源加载时间、页面渲染时间等。它可以触发回调函数,以便你收集和分析页面性能数据。 优点 1. 性能...
学习

评论

请登录后发表评论

去登录
加载评论中...

目录