rrweb入门

news2024/9/29 8:50:49

rrweb

背景

rrwebrecord and replay the web,是当下很流行的一个录制屏幕的开源库。与我们传统认知的录屏方式(如 WebRTC)不同的是,rrweb 录制的不是真正的视频流,而是一个记录页面 DOM 变化的 JSON 数组,因此不能录制整个显示器的屏幕,只能录制浏览器的一个页签(录屏)。

  • rrweb事例展示
  • 流程图

image.png

意义解决问题

  • 用户分析(常规的指标数据,只能做到一个统计。如果能通过录屏,我们能完整分析某个客户的行为。)

  • 重现bug(客户说有bug,但是复线不了,环境不一样,数据不一样。我们只能推断,但是有了录屏,我们就能很好的还原现场,知道本质操作)

  • 代替视频录制 (录制体积更⼩、清晰度⽆损的产品演⽰。(纯粹是html,不用装插件))

基本使用

安装

npm install rrweb

录制

通过 rrweb.record 方法来录制页面,emit 回调可接收到录制的数据。

import rrweb from 'rrweb';
// 1.录制
let events = []; // 记录快照

rrweb.record({
  emit(event) {
    // 将 event 存入 events 数组中
    events.push(event);
  },
});

image.png

回放

通过 rrweb.Replayer 可回放视频,需要传递录制好的数据。

// 2.回放
const replayer = new rrweb.Replayer(events);
replayer.play();

原理透析

基本概念

image.png

rrweb-snapshot 快照的生成

将页面中的dom转化为可序列化的数据结构并添加唯一标识

例如以下的 DOM 树:

<html>
  <body>
    <header>
    </header>
  </body>
</html>

会被序列化成类似这样的数据结构:

{
  "type": "Document",
  "childNodes": [
    {
      "type": "Element",
      "tagName": "html",
      "attributes": {},
      "childNodes": [
        {
          "type": "Element",
          "tagName": "head",
          "attributes": {},
          "childNodes": [],
          "id": 3
        },
        {
          "type": "Element",
          "tagName": "body",
          "attributes": {},
          "childNodes": [
            {
              "type": "Text",
              "textContent": "\n    ",
              "id": 5
            },
            {
              "type": "Element",
              "tagName": "header",
              "attributes": {},
              "childNodes": [
                {
                  "type": "Text",
                  "textContent": "\n    ",
                  "id": 7
                }
              ],
              "id": 6
            }
          ],
          "id": 4
        }
      ],
      "id": 2
    }
  ],
  "id": 1
}

这个序列化的结果中有两点需要注意:

  1. 我们遍历 DOM 树时是以 Node 为单位,因此除了场景的元素类型节点以为,还包括 Text Node、Comment Node 等所有 Node 的记录。
  2. 我们给每一个 Node 都添加了唯一标识 id,这是为之后的增量快照做准备。

在完成一次全量快照之后,我们就需要基于当前视图状态观察所有可能对视图造成改动的事件,在 rrweb 中我们已经观察了以下事件(将不断增加,增量序列化):

  • DOM 变动

    • 节点创建、销毁
    • 节点属性变化
    • 文本变化
  • 鼠标移动

  • 鼠标交互

    • mouse up、mouse down
    • click、double click、context menu
    • focus、blur
    • touch start、touch move、touch end
  • 页面或元素滚动

  • 视窗大小改变

  • 输入
    类似git ,先提交一个版本,每次再追加追加。

记录的方法: MutationObserver

  • MutationObserver 是一个用于监听 DOM 变化的 JavaScript 接口。触发方式为批量异步回调,一系列dom 变化之后,通过其回调函数开始接收通知。MutationObserver 可以监听节点的添加、移除、属性变化等操作。
序列化中的特殊处理(只是对dom变化做了记录)

之所以说我们的序列化方法是非标准的是因为我们还需要做以下几部分的处理:

  1. 去脚本化。被录制页面中的所有 JavaScript 都不应该被执行,例如我们会在重建快照时将 script 标签改为 noscript 标签,此时 script 内部的内容就不再重要,录制时可以简单记录一个标记值而不需要将可能存在的大量脚本内容全部记录。
  2. 记录没有反映在 HTML 中的视图状态。例如 <input > 输入后的值不会反映在其 HTML 中,而是通过 value 属性记录,我们在序列化时就需要读出该值并且以属性的形式回放成 。
  3. 相对路径转换为绝对路径。回放时我们会将被录制的页面放置在一个<iframe>中,此时的页面 URL为重放页面的地址,如果被录制页面中有一些相对路径就会产生错误,所以在录制时就要将相对路径进行转换,同样的 CSS 样式表中的相对路径也需要转换。
  4. 尽量记录 CSS 样式表的内容。如果被录制页面加载了一些同源的 样式表,我们则可以获取到解析好的 CSS rules,录制时将能获取到的样式都 inline 化,这样可以让一些内网环境(如 localhost)的录制也有比较好的效果。

序列化

任何语言,数据都是由数据结构来表示的,我们将数据结构转换成二进制,字符串的过程就是序列化

rebuild

  • 将snapshot 记录的数据结构重建为对应的DOM

rrweb-player

为rrweb 提供的一套UI 控件,提供基于GUI的

录制原理

MutationObserver

播放阶段

在序列化设计中我们提到了“去脚本化”的处理,即在回放时我们不应该执行被录制页面中的 JavaScript,在重建快照的过程中我们将所有 script 标签改写为 noscript 标签解决了部分问题。但仍有一些脚本化的行为是不包含在 script 标签中的,例如 HTML 中的 inline script、表单提交等。

脚本化的行为多种多样,如果仅过滤已知场景难免有所疏漏,而一旦有脚本被执行就可能造成不可逆的非预期结果。因此我们通过 HTML 提供的 iframe 沙盒功能进行浏览器层面的限制(隔离环境,嵌入其他应用,兼容性考虑)。
rrweb 的播放器是在一个 iframe 上回放录屏的,为了阻断 iframe 上的用户交互需要做一些特殊处理,比如在 iframe 标签上设置 CSS 属性:

pointer-events: none;

为了去脚本化,将 <script> 标签替换为 <noscript> 标签,另外将 iframe 的 sandbox 属性设置为 “allow-same-origin”,可以防止任何脚本的执行。

  1. 高精度计时器
  2. 补全缺失节点
  3. 模拟hover
  4. 从任意时间开始播放

高精度计时器

之所以强调回放所⽤的计时器是⾼精度的,是因为原⽣的 setTimeout 并不能保证在设置的延迟时间之后准确执⾏,例如主线程阻塞时就会被推迟。

对于我们的回放功能⽽⾔,这种不确定的推迟是不可接受的,可能会导致各种怪异现象的发⽣,因此我们通过 requestAnimationFrame(根据设备的屏幕刷新率来调整动画的帧率) 来实现⼀个不断校准的定时器,确保绝⼤部分情况下操作的重放延迟不超过⼀帧。

同时⾃定义的计时器也是我们实现“快进”功能的基础。

补全缺失节点

rrweb 中,当进行页面重放过程中,如果发现了缺失的节点,它会通过补全缺失节点的方式来还原页面的完整状态。

页面重放的过程是通过按照操作的记录序列逐步还原页面状态的。记录的操作序列包括了用户在页面上执行的各种操作,比如点击、输入等。这些操作会导致页面上的节点发生相应的变化,包括添加、删除、修改等。

然而,在记录操作序列的过程中,可能会发生节点变化的时机比较复杂的情况,比如动态插入节点、使用 Shadow DOM、异步加载等。这些情况会导致在记录过程中无法捕获到节点变化的信息,导致记录的操作序列中缺失了节点的变化信息。

为了解决这个问题,rrweb 会使用 MutationObserver 监听页面上节点的变化。当发现有节点被添加或删除时,rrweb 会将这些节点的信息记录下来,并结合之前记录的操作序列进行分析。通过分析节点的变化情况,以及操作序列中的操作类型和位置rrweb 可以推断出缺失的节点应该是什么,并进行补全。

模拟 Hover

从任意时间点开始播放

除了基础的回放功能之外,我们还希望 rrweb-player 这样的播放器可以提供和视频播放器类似的功能,如拖拽到进度条至任意时间点播放。

实际实现时我们通过给定的起始时间点将快照链分为两部分,分别是时间点之前和之后的部分。然后同步执行之前的快照链,再正常异步执行之后的快照链就可以做到从任意时间点开始播放的效果。

播放器的进度条是如何控制与每个增量快照发生的时间对应上呢?

比如在播放时用户点击进度条上的某一点,这一点距离初始时间点是 timeOffset 长度,点击的这个点可以叫做基线时间点 baselineTime,rrweb 会根据这个点将所有的事件分成两部分:前一部分是在基线时间点前已经发生的事件队列,后一部分是待回放的事件队列。把前一部分事件同步还原构建完成,作为后面队列的全量基准 DOM 树,再继续异步地按照正确的时间间隔构建后面的增量快照。

问题扩展

如何将rrweb 转化为视频

  • rrvideo
    puppeteer 在服务端运行无头浏览器,在无头浏览器中回放录制的数据,然后每秒截取一定数量的图片,最后通过 ffmpeg 合成视频。下面是大致的流程图

image.png

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/984336.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件上传漏洞-upload靶场13-16关 (图片木马-文件包含与文件上次漏洞)

文件上传漏洞-upload靶场13-16关 &#xff08;图片木马-文件包含与文件上次漏洞&#xff09; 简介 upload靶场到了第十三关&#xff0c;难度就直线上升了&#xff0c;在最后这7关中&#xff0c;包含了图片木马、竞争条件等上传技巧&#xff0c;这些漏洞的本质&#xff0c;都是…

算法:数组常见套路1---双指针、取模、打擂台法

一、数组的合并–双指针[快慢指针] 1、题目&#xff1a; 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺…

MybatisPlus(3)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 一、查询投影&#x1f36d; 查询投影是指在查询操作中&#xff0c;只选择…

管理类联考——数学——汇总篇——知识点突破——数据分析——计数原理——排列组合——单排与环排

&#x1f451; 公式&#xff1a;—般地&#xff0c;n个不同元素作圆形排列&#xff0c;坐成圆形没有首尾之分&#xff0c;所以固定一人&#xff0c;共有 ( n − 1 ) ! (n-1)! (n−1)!种排法。如果从n个不同元素中取出m个元素作圆形排列共有 1 m C n m \frac{1}{m}C_n^m m1​Cn…

Windows Server 系统各版本及授权说明(附下载地址

本文为Windows Server系统各版本差异对比及授权说明。 会对相关目前仍主流使用的相关Windows Server系统版本和相关授权进行对比和功能说明。 WindowsServer2012 R2 Windows Server 2012 R2授权方式是按照物理CPU数量进行授权&#xff0c;比如物理服务器CPU插槽数量2&#xff…

企业数字化神经网络

随着数字化时代的到来&#xff0c;数据已经成为企业战略性资源和重要的生产要素。企业数字化转型的核心是充分开发和利用数据资源&#xff0c;以数据为驱动&#xff0c;对业务流程进行重构与创新&#xff0c;从而提升企业的核心竞争力。业务系统是企业数据资源的源头&#xff0…

Gitlab常用命令总结汇总

Gitlab常用命令 本地 初始化 全局变量 全局配置 git config --global user.name "your name" #设置全局用户名#git config --global uer.email "your email" #设置全局邮箱#版本库配置 git config --global color.ui true #让Gitlab显示不同的颜色…

吹爆这款制作电子图册的工具,真是太绝了

近年来&#xff0c;随着互联网技术的不断发展&#xff0c;电子图册成为了一种越来越受欢迎的展示方式。然而&#xff0c;对于很多人来说&#xff0c;制作电子图册并不是一件容易的事情。幸运的是&#xff0c;现在有一款神器出现了&#xff0c;让制作电子图册变得轻而易举。 这款…

易点易动库存管理系统与ERP系统打通,帮助企业实现低值易耗品管理

现今,企业管理日趋复杂,无论是核心经营还是辅助环节,都需要依靠信息化手段来提升效率。而低值易耗品作为企业日常运营中的必需品,其管理也面临诸多挑战。传统做法效率低下,容易出错。如何通过信息化手段实现低值易耗品的高效管理,成为许多企业必顾及的一个课题。 易点易动作为…

Mac电脑怎么使用NTFS磁盘管理器 NTFS磁盘详细使用教程

Mac是可以识别NTFS硬盘的&#xff0c;但是macOS系统虽然能够正确识别NTFS硬盘&#xff0c;但只支持读取&#xff0c;不支持写入。换句话说&#xff0c;Mac不支持对NTFS硬盘进行编辑、创建、删除等写入操作&#xff0c;比如将Mac里的文件拖入NTFS硬盘&#xff0c;在NTFS硬盘里新…

【C++】详解AVL树并模拟实现

前言&#xff1a; 之前我们为了让数据存储效率提高&#xff0c;引进了二叉搜索树。 但是我们发现&#xff0c;二叉搜索树的时间复杂度还是O(N),因为二叉搜索树并不是非常的平衡。 并不是所有树都是满二叉树&#xff0c;可能出现单边书这样极端的情况&#xff0c;所以我们引进…

Compose的一些小Tips - 生命周期

系列文章 Compose的一些小Tips - 生命周期&#xff08;本文&#xff09; 前言 本系列介绍Compose的一些常识&#xff0c;了解这些tips并不会让人摇身一变成为大佬&#xff0c;但可以帮助到一些学习Compose的安卓开发者避免一些误区&#xff0c;也是对入门详解中遗漏的一个补充…

智能水表远程控制系统:引领节水新时代

随着科技的不断发展&#xff0c;物联网技术逐渐融入到我们的日常生活中。其中&#xff0c;智能水表远程控制系统成为一项重要创新&#xff0c;对于提高水资源利用率、实现绿色节水具有重要意义。下面小编就来为大家介绍下智能水表远程控制系统吧! 一、智能水表远程控制系统定义…

发现一个超级神器:免费素材共享的引领者——微信公众号的“ 素材帮帮站”

博主是做软件开发的&#xff0c;拥有10年的软件开发经验&#xff0c;奈何在这个内容为王的时代&#xff0c;软件开发行业太难混了&#xff0c;在公司的安排下&#xff0c;做一些图片设计的工作。最近发现一个超级神奇&#xff0c;免费&#xff0c;全面&#xff0c;更新迅速的微…

尺度空间和使用各向异性扩散进行边缘检测——Scale-Space and Edge Detection Using Anisotropic Diffusion

0.摘要 由Witkin引入的尺度空间技术涉及使用高斯核将原始图像与卷积以生成更粗糙的分辨率图像。这种方法有一个主要缺点&#xff1a;在粗糙的尺度上准确获取“语义上有意义”的边缘位置很困难。在本文中&#xff0c;我们提出了尺度空间的新定义&#xff0c;并引入了一类利用扩散…

把握市场潮流,溯源一流品质:在抖in新风潮 国货品牌驶过万重山

好原料、好设计、好品质、好服务……这个2023&#xff0c;“国货”二字再度成为服饰行业的发展关键词。以消费热潮为翼&#xff0c;越来越多代表性品类、头部品牌展现出独特价值&#xff0c;迎风而上&#xff0c;在抖音电商掀起一轮轮生意风潮。 一个设问是&#xff1a;在抖音…

MT9700 80mΩ,可调快速响应限流配电开关芯片

MT9700 80mΩ&#xff0c;可调快速响应限流配电开关芯片 特征 符合USB规范 集成80mΩ电源MOSFET 低电源电流 15μA典型开启状态 1μA典型关闭状态 宽输入电压Range&#xff1a;2.4V到5.5V 快速瞬态响应&#xff1a;<2μs 反向电流流阻塞 热关机保护 热插件应…

音视频FFmpeg简单理解学习,必学技术

FFmpeg是一个开源的多媒体框架&#xff0c;它包含了一个用于音频和视频编解码的库。它可以执行各种多媒体操作&#xff0c;如格式转换、视频剪辑、音频处理等。可以用来记录、转换数字音频、视频&#xff0c;并能将其转化为流的开源计算机程序。 FFmpeg的结构 默认的编译会生成…

FPGA的基础架构,什么是CLB?

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处 CLB是指可编程逻辑功能块&#xff08;Configurable Logic Blocks&#xff09;,顾名思义就是可编程的数字逻辑电路。CLB是FPGA内的三个基本逻辑单元。C…

二叉树题目:填充每个结点的下一个右侧结点指针 II

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;填充每个结点的下一个右侧结点指针 II 出处&#xff1a;117. 填充每个结点的下…