资讯专栏INFORMATION COLUMN

基于rrweb录屏与重放页面

Crazy_Coder / 2433人阅读

摘要:后面当页面发生变化时,只对变化的元素进行序列化。当重放页面时,会将数据反序列化并插入到页面中,而原先增量的变化,如属性或者文本变化,则根据找到对应元素修改而子节点的增加或减少,根据父元素进行变更。

项目背景

在使用ant design文档的过程中发现,antd使用了一个叫做logRocket的录屏框架,于是立马将logRocket用在自己的项目当中,测试它的功能。

logRocket网站将采集到的数据,按照人员和session进行分类,观看各人员的操作回放,可以发现系统中某些操作的不便之处,并且可以发现哪些人员是你的重度用户。

但是logRocket的数据存储在他们的服务器,并且从logRocket回放里,能看到系统中的各种重要数据。如果数据被别有用心之人获取,后果将很严重。

rrweb

如果我们需要基于一个开源框架,并将数据存在自己的服务器中,限制人员查看的权限,这样就尅消除之前的隐患。

下面我要介绍的就是今天的主角rrweb框架,全称record and replay the web。它由三个库组成:

rrweb-snapshot,将页面中的dom转化为可序列化的数据结构

rrweb,提供录屏和重放的api

rrweb-player,提供播放的ui页面,支持快进、全屏、拖拽等操作

每次刷新页面时,rrweb会将页面中的dom元素全部转换成文档数据,并给每个dom元素分配一个唯一id。后面当页面发生变化时,只对变化的dom元素进行序列化。当重放页面时,会将数据反序列化并插入到页面中,而原先增量的dom变化,如属性或者文本变化,则根据id找到对应dom元素修改;而子节点的增加或减少,根据父元素id进行dom变更。

开发历程

1.直接使用rrweb记录每次的序列化录屏数据,首先保存到localStorage中,当数据量超过阈值或者超过时间限制,再由sendbeacon发送数据到node,并保存到mongo中。

2.首先遇到的问题是sendbeacon发送数据居然出现了丢失,原因是数据超过65536时,将会发送失败,由于sendbeacon是由后台进程多带带发送,无法获取失败状态,所以要进行降级处理,当数据过大时,使用fetch请求发送。

3.由于公司中后台系统的用户分布在世界各地,海外的网络延迟较高,需要解决压缩数据大小的问题,这里使用的是lz-string库。一开始想要在每次存储在localStorage时进行压缩,后来发现压缩后的数据有特殊字符,JSON.parse高频率出错,后改为在每次发送数据到后端之前压缩,并在node端进行解压。

4.一开始的数据库选型为时序数据库influxdb,由于某些不可抗拒原因改为了mongodb。

5.在项目上线后选择了一个小项目进行测试,发现存储和播放效果良好,代码如下

import rrweb from "rrweb";

rrweb.record({
  emit(event) {
    storagePush(event);
  },
});

存进数据库中的数据结构为

{
timestamp: 1563418490795,
name:"小明",
event:...
}

方便按照用户和时间范围进行查找数据,内容如下

6.但是每次都要播放一整天的数据,第一播放接口获取的数据量巨大,第二播放时间漫长,抓不住重点,一旦数据有误导致后续录屏都播放不了。

查看rrweb源码发现checkoutEveryNms属性可以按照时间进行session切分,于是代码变成了这样

rrweb.record({
  emit(event, checkout) {
    if(checkout)rrwebSessionSet();
    storagePush(event);
  },
  checkoutEveryNms: 1000 * 60 * 10
});

每一次checkoutEveryNms到期时,emit里的第二个参数checkout都会为true,这样就可以知道新的session开始,给session分配一个唯一值,存到数据库中的数据结构改为这样

{
timestamp: 1563418490795,
name:"小明",
session:xxxxxxxxxxx,
event:...
}

有了session概念之后,某个人某一天的操作就可以按照session进行选择


播放页面如下

7.小项目测试完毕后,希望引入一个大项目进行测试,于是开放了一个uv上千、pv几十万的大项目,采集一天的数据后,发现存储数据正常,而播放页面已经获取不到数据,查看mongo的stats发现一天存储量达到了1500万条,每一条数据基本在几十KB到几M之间。

首先对不同的项目进行分表存储,并将索引设置为后台处理,这个方案使用后播放页面变得正常,但人员列表接口还是很慢。

于是在每次存储mongo时,存一份人员和日期的数据到redis中,目前系统已经正常运行,所有接口能在1s内返回所有数据。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105787.html

相关文章

  • 网页应该如何录屏呢?

    摘要:用于将及其状态转化为可序列化的数据结构并添加唯一标识则是将记录的数据结构重建为对应的。用于记录中的所有变更则是将记录的变更按照对应的时间一一重放。表示观察变动时,是否需要记录变动前的属性值。该方法返回变动记录的数组。 摘要: 网页应该如何录屏呢? 作者:Winty 原文:用户行为录帧调研 Fundebug经授权转载,版权归原作者所有。 关键点 首先,每一次会话都有一个唯一的s...

    _Suqin 评论0 收藏0
  • 初识React

    摘要:初识依稀记得那年参加线下活动,第一次听说这个词语,当时的主讲人是郭达峰,他播放了一个关于及的性能对比视频。合成事件会以事件委托的方式绑定到组件最上层,并且在组件卸载的时候自动销毁绑定的事件。 初识React 依稀记得2015那年参加线下活动,第一次听说React这个词语,当时的主讲人是郭达峰,他播放了一个关于ember、angular及react的性能对比视频: React.js Co...

    kuangcaibao 评论0 收藏0
  • 数据浪潮之间的前端工程师

    摘要:数据浪潮之间的前端工程师十年来,波澜壮阔的移动互联网浪潮促进了技术的迅猛发展,随着浏览器性能网络带宽等基础设施的提升,也能够承载起包含复杂交互可视化计算逻辑需求的富客户端应用。 showImg(https://segmentfault.com/img/remote/1460000016874425); 本文是架构师 2018-10 月刊的卷首语,归纳于自笔者的技术之路系列文章,也是对 ...

    mdluo 评论0 收藏0
  • 前端小报 - 201812 月刊

    摘要:也能帮你写代码了微软和团队一起推出扩展,预览版可以在插件市场直接查找安装。微软宣布将采用内核这对于诸多的前端开发者而言,无疑是本年底最大的福音具体的计划可以参考官网的博客,在不久的将来,基于的浏览器将要正式和我们见面啦。 订阅 / 投稿:https://github.com/txd-team/monthly本期小编: Hkmu (扶容) / x-cold (尹挚) 新闻快报 npm ...

    Coding01 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<