本篇文章来自团队小伙伴 @陈小信 的一次学习同享,期望跟咱们同享与评论。

求积硅步致使千里,勇于探享日子之美。

前端录制回放体系初体验

问题布景

什么是前端录制回放?

望文生义,源码编辑器就是录制用jsonp户在网页中的各种操作,而且源码分享网支撑能随时回Java放操作。

为什么源码本钱需求?

说到需求就不得json是什么意思不说一个经典的场景,一般前端做异常监控和差错上报源码网站,会选用自研或接入第三方 Sjson解析DK 的方法,来源码编辑器手机版下陈思思收集和上报网站交互进程中 JavaScript 的报错信息长沙师范学院和其它相关数据json格局,也就是埋点。

在传统的埋点计划中,依据 SourceMap 能定位到详细报错代码文件CSS和部队信息等。根天性定位大部分场景问题,但有一些状况下是很源码超市难复现差错,多是在检验扯皮html简略网页代码的时分,程序员口头禅之一(我这儿没有报错呀,是不是你Javajavascript电脑有问题)。

要是能把犯json格局怎样翻开错的操作进程录制下来就好了,这样就能便利咱们复现场景了,且留存证据,好像是自己给自己挖了个坑。

怎样完毕?java言语

前端能完毕java环境变量装备录视json是什么意思频?我第一反响就是质疑,接着我就是一波 Google ,发现的确有可行计划。

Google 之前,我想到了经过设定定仓鼠寿数时器,对视图窗口进行截图,截图可用 canvas2html 的方法来完毕,但这源码集市种方法无疑会构源码年代java言语功能问题,立马否决。

下面介绍我所「知道」的 Google 的计划,如有问题,欢迎纠正。

思路初现

网页本质上是一个 DOM 节点方法存在,源码年代经过浏览器烘托出来。咱们是否能够把 DOM 以某种方法保存起来,并源码且在不同时刻节点持续记载 DOM 数据状况。再将数据康复成 DOM 节点烘托出来完毕回放呢?

操作记载jsonp跨域原理

经过 documentjson格局怎样翻开.documentElement.cloneNojsonpde陈思思() 克隆到 DOM 的数据方针,此时这个数据不java面试题能直接经过接口传输给后端,需求进行一些格局化预处理,处理成便源码网站当传输及存储的数据格局。最简源码集市单的方法就是进行序列化,也就是转换成 JCSSSON 数据格局。

// 序列化后
let docJSON = {
"typejava言语长沙师范学院": "Document源码本钱",
"childNodes": [
{
"tyjsonpe": "Element超神兽宠店",
"tagName": "html",
"attributes":超崇高骑士 {},
"chjavascriptildNodes": [
{
"type": "Element",
"tagName": "hea崇圣寺三塔d",
"ajson文件是干什么的ttrijson转mapbutes": {},
"childNodes": []
}
]
}
]
}

有无缺的 DOM 数据之后,还需求在 DOM 改动时进行监听,记载每次java怎样读改动的 DOM 节点信息。对数据进行监听可用 MutationObshtml是什么意思erver,它是一个能够监听 DOM 改动的 API陈思思

conshtml个人网页完好代码t observer = new MutationObserver(mutationsList => {
console.log(mutationsList); // 发生改动的数据
});
// 以上述装备初步查询方针节点
observer仓鼠寿数.observe(document, {});

除了对 DOM 改动进行监听以外,还有一个就是作业监听,用户与网页的交互多是经过鼠标,键盘等输入设备来进行。而这些交互的背面便JavaJavaScript 的作业监听。作业监听能够html标签特色大全经过绑定体系作业来完毕,同样超崇高骑士是需求记载下来,以鼠标移动为例:

// 鼠标移动
document.addEventListener('mousemove', e => {
// 伪代码 获取鼠标移动的信息并记载下来
positions.push(html简略网页代码{
x: clientX,
y: clien长沙师范学院tY,
timeOffset: Date.now() - timeBaseline,
});
});

addEvenjson转maptListjson文件是干什么的ener能够绑定多个相同作业,不影响开发者的作业绑定

回放操作

数据超神兽宠店已经有了,接着就是回放,回放本质上是将 JSjsojsonnON 数据康复成 DOM崇圣寺三塔点烘托出来。JSON那就将快照数据康复就能够啊「嘴强王者」,数据康复并非那么简略啊!

烘托环境

首要为了确保回放进程代码隔绝,需求沙箱环境, iframe 标签能够做到,而且 iframe 供应了 sandbox 特征可配java怎样读备沙箱。沙箱环境的json格局怎样翻开作用是确保代javaee码安全而且不被烦扰。

<iframe sandbox srcdoc></iframe&javaeegt;

sanbox 特征能够做到沙箱作用,点击查看源码文档

srcdoc 能够直接设置成一段 html 代码

数据康复

快照重组首要是 DOM 节点的重组,有点像虚超神兽宠店DOM 转成实在文档java根底知识点节点的进程,可是作业类型快照是不需求重组。

定时器

有了数据和环陈思思境,还需求定时器。通Java过定时器不断烘托 DOM ,实质上就是一个播映视频的作用, requestAnimationFrame 是最合适的。

reque陈涉世家翻译及原文sthtml个人网页无缺代json格局怎样翻开Animathtmliojsonp跨域原理nFrame 实施机制在浏览器下一次 repain(重绘)之前实施,实施频率取决于浏览器改写频率,更合适制html是什么意思作动画作用

至此长生十万年有一个大约的主见,间隔落地仍是有段间隔。得益于开源,咱们java言语可上 Github 看看有没有合适的轮子可仿制(学习),刚好有现成的一结构 「rJavarweb」,不妨一起看看。

rrweb 结构

rrweb 是一个前端录制和回放的结构。全称 record and replay the web ,望文生义就是能够录制和回放 web源码编辑器手机版下载java编译器 界面中的源码操作,其间心原理就是上面介绍的计划。

rrwjsonpeb 组成

rrweb 包括三个部分:

  • rrweb-snaphtml5sho源码本钱t 首要处理 DOM 结构序列化和重组;
  • rrweJSONb 首要功用是录制和回放;
  • rrweb-pljson是什么意思a源码网yer 一个视频播映器 UI 空间

rrwjson是什么意思html是什么意思eb 运用

npm 装置习以为常,import/require 引入问题不大

源码网站

经过 rhtml文件怎样翻开rweb.record 方法来录制页面,emit 回调可承遭到录制的数据。

// 1.录制
let events = []; // 记载快照
rrwebJava.record({
emit(event) {
// 将 event 存入java编译陈涉世家翻译及原文 events 数组中
events.push(event);
},
}源码编辑器手机版下载);

回放

经过 rrweb.Replayer 可回放视频,需求传递录制好源码之家的数据。

// 2.回放
cons崇圣寺三塔t replayer = new rrweb.Replayer(events);
replayer.play();

点击查看官计划例作用

rrweb 源码

依照以上所说的思路,接下来会解析其间一些要害代码,当源码网然只是在我个人了解上做的一些仓鼠寿数分析,实java环境变量装备际上 rrweb 源码远不止这些。

前端录制回放体系初体验

中心部分为三大块: record (录制)、 replay 回放、 snapshot 快照。

R陈涉世家翻译及原文ecord 录制

DjavascriptOM 加载完毕后,record 会做一次无缺的 DOM 序列化,咱们把它叫做全量快照,全量快照记载了整个 HTML 数据结构。

record.ts 中找到要害的进口json函数长沙师范学院的界说 init,进口函数是会在 document 加载完毕或(可交互html5,完毕)时调用了 tjava根本数据类型akeFullSnapjson是什么意思shot 以及 obsjson解析erve(document) 函数。

if陈思思 (
document.readyState ===源码编程 'interactive'长生十万年 ||
document.readyState === 'complete'
) {
init();
} els超神兽宠店e {
//...
ohtml简略网页代码n('load',() => { injava言语it(); },),
}
conjson是什么意思st init = () => {
takeFullSnapshot(); // 生满足量仓鼠寿数快照
handlers.pusjavaeeh(observe(documen源码超市t)); //监听器
};

dohtml个人网页无缺代码cument.源码年代readyState 包括三种状况:

  1. 可交源码java怎样读编辑器in源码编辑器编程猫下载terajson是什么意思ctive
  2. 正在加载中 loading
  3. 完毕 complete

takeFullSnapshot 从字面意思能看出其作用是生成「无缺」的快照,也就是会HTMLjson格局怎样翻开 dojson格局cument 序列化出一个无缺HTML的数据,称之为 「全量快照」

一切序列化相关操作都是运用 snapshot 完毕,snapshot 接受一个 dom 方针和一个装备方针传递 document 将整个页面java环境变量装备序列化得到完毕的快照数据。

// 生满足量快照
takeFullSnapshot = (isCheckout = false) => {
//...
const [node, idNodeMap] = snapshot(dojava编译器cument, {
//...一些装备项
});
//...
}html

idNodeMap 是一个 idkey ,html标签特色大全DOM 方针为 valuekey-va陈涉世家翻译及原文lue 键值对方针

observe(dohtml网页制造cument) 是一些监听器的初始化,同样是将整个 document 方针传长沙市气候曩昔进行监听,经过调用 initObservers 来初jsonp始化一些监听器。

const observe = (doc: Document) => {
return initObserjsonvers(//...)
}

observer.t源码编辑器编程猫下载s 文件中能够找到 initObservers 函数java模拟器界说,该函数初始化了 11 个监听器,json格局能够分为 DOM 类型 / Event 作业类型 / Media 媒体三大类html网页制造

expo源码超市rt function initObservers(
// dom
const mutajson解析tionObserver = initMutationObserver();
const mousemoveHandler = initMoveObserver();
const mouse仓鼠寿数InteractionHandjava模拟器ler = initMouseInteractionObserver();
const scrollHandler = initSjavaeecrollObserver();
cons源码之家t vijavaeeewporthtml网页制造ResizeHandler = initViewportResizeObserver();
// ...
)
  • DJSONOM 改动监听器,首要有 DOM 改动(增修改html网页制造), 款式改动,java底子数据长沙师范学院类型仓鼠寿数心是经过 MutationObserver 来完毕

    let mutationO源码本java编译器bse源码编程rverChtmltor = window.MutationObserver;
    conjavaeest observer = new mutationObserverCtor(
    // 处理改动的数据
    mujava编译器tationBuffer.procejson格局ssMutationjsonp跨域原理s.bind(mutationBuff源码同享网er),
    );
    ohtml标签HTMLbserver.observe(doc, {});
    return observer;
    
  • 交互监听-以鼠标移动 initjhtmlava面试题MoveObserver 为例

// 鼠标移动记载
function initMoveObserver() {
c源码编程onst u源码本钱pda源码编辑器编程猫下载tePosition = throttle<M源码本钱ouseEvent | TouchEvent>(
(evt) =JSON> {
positions.push({
x: clientX,
y: clientY,
});
});
const handlers = [
on('mousemove', updatePosition, doc),
on('touchmove', updatePosition, dojava仿照器c),
];
}
  • 媒体类型监听器,有 canvas / video / audiohtml5,以 vi崇圣寺三塔deo 为例,本质上记载json是什么意思播映和暂停状况,mediaInteractionCjson是什么意思bplay / pause 状况回调出来。
function initMediaInteractionObserver(): listenerHandler {
mediaInteraction源码Cb({
type源码编辑器: type === 'play' ? Medi源码编程aInteractions.Play : MediaInteractions.Pause,
id:json文件是干什么的 mirror.getId(target as INode),
});
}

Snapshot 快照

snapshot 担任序列化和重组的功用,首要经过 serializeNodeW源码编辑器ithId源码网站 处理 DOM 序列化和 rebuildWithSN 函数处理 DOM 重组。

seriahtml是什么意思lizeNodeWithId 函数担任序列化,java面试题首要做了三件事:

  • 调用 se长沙市气候rializeNode源码集市列化 Njava面试题ode
  • 经过 ge源码nIjso源码编辑器编程猫下载nd() 生成仅有ID 并绑定到 Node 中;
  • 递归完毕序列化子节java根底知识点点,并究竟回来json解析一个带 ID 的方针html标签特色大全
// 序列化一json是什么意思个带有ID的DOM
export functi崇圣寺三塔on seriajava底子数据类型lizejson文件是干什么的NodeWithId(源码编辑器手机版下载n) {
// 1. 序列化 中javascript心函数 serializeNode
const _serialhtml代码izedNode源码集市 = serializeNode(n);
// 2. 生成仅有IDhtml网页制造源码编辑器
let id = genId();
// 绑定ID
const serializedNode = Object.assign(_serializedNode, { id });
// 3.子节点序列化-崇圣寺三塔源码网站递归
forjavaee (cons超神兽宠店t childN of Array.from(n.childNodes)) {
conjsonpst serializedChildNode = serializeNodeWithId(ch长沙市气候ildN, bypassOptions);
ifhtml是什么意思 (serializedChildjson转mapNode) {
s源码编辑器erializedNode.childNodes.push(serializedCHTMLhildNode);
}
}陈涉世家翻译及原文
}

serializeNodeWithId 中心是经过 serializeNode 序列化 DOM ,针对不同的节点分别做了一些特殊处理。

节点特征的处理html个人网页无缺代码:

fo源码超市r (const { name, value } of Array.from((n as HTMLElement).attributes)) {
ajava面试题ttributes[name] = transformAttribute(doc, tagName陈涉世家翻译及原文, nhtml标签am源码同享网e, value);
}

处理外联 css 款式,经过 getCssRul源码集市esString 获取到详细款式代码,而且储存到 attributes 中。

consthtml文件怎样翻开 cssTejsonxt = getCssRuhtml个javascript人网页无缺代码lesString(stylesheet as CSSStyleSheet);
if (cssText) {
attributesjava环境变量装备._cssText = absoluteToStylesheet(
cssText,
stylesheet!.hrjson怎样读ef!,
);源码年代
}

处理 form 表单,逻辑是保存选中状况,而且做了一些安全处理html标签特色大全,例如暗码框内容替换成 *

if (
attributes.t长生十万年y崇圣寺三塔pe !=源码= 'radio' &&
attribujava言语te源码网站s.type !== 'checkbojava底子数据类型x' &&amhtml标签p;json文件是干什么的
// ...
) {
attribjajava面试题va言语utes.value = maskInputOptions[tagNa源码网me]
? '*'json是什么意思.repea长沙市气候t(value.length)
: value;
} else if (n.源码网站checked) {
attribuJSONteshhtml5tml简略网页代码.checked = n.checked;
}

canvas 状况保存经过 toDataURL 保存 canvas 数据:仓鼠养殖八大忌讳

attributes.rr_dataURL = (n as HTMLCanvasElement).tjson解析oDataURL();

rebuhtml文件怎样翻开ild 担任重建 DOM :

  • 经过 b源码集市uildhtmlNodeWithSN 函数重组 Node
  • 递归调用 重组子节点
export function b源码年代uildNodeWithSN(n) {
// DOM 重组中心函数 buildNode
let node = buildNode(n, { doc, hackCss });
// 子节点重建而且appen源码网dChild
for (const childN of n.childNodes) {超崇高骑士
c陈涉世家翻译及原文onst childNode = buildNodeWithSN(childN);源码编辑器
if (afterAppend)源码编辑器手机版下载 {
afterAppend(childNode源码);
}
}
}

Repjson怎样读lay 回放

回放部分在 replahtml个人网页无缺代码y源码网.ts 文件中,先创建沙箱环境,json转map接着或进行json解析源码之家document 全量快照,在经过 requestAnim超崇高骑士ajava编译器tionFrame 仿照定时器的方法来播映增量快照。

replay 的结构函数接纳两个参数,快照数据 events 和 装备HTMLconfig

exphtml标签ort cjson是什么意思lass Replayer {
constrjava根本数据类型ujson格局ctor(eve源码同享网nts, confi陈思思g) {
// 1.创建沙箱环境
this.setupDom();
// 2.定时器
const timer = new Timer(jsonp);
// 3.播映服务
this.service = new crehtml代码atePjsonlayHTMLerService(events, timer);
this.仓鼠寿数service.start();
}
}

结构函数中最中心三步,创建沙箱环境,定时器,陈涉世家翻译及原文和初始化播映器而且建议。html5播映器创建依靠 eventstimer ,本质上仍是运用 timer 来完毕播映。

沙箱环境

首要,在 replhtml是什么意思ay.ts 的结构函数中能够找打 this.setupJavaDom 的调用,shtml网页制造etupDom 中心是经过 iframe 来创建出一个沙箱环境。

private源码网站 setupDom() {
// 创建iframe
this.iframe = dojava根本数据类型c源码编程ument.createElement('iframe');JSON
this.iframe.style.display = 'none';
this.iframe.setAttribute('sandbox'超神兽宠json转map, attribu源码本钱tes.源码超市join(' '));
}

播映服务

同样在 replay.tshtml标签特色大全构函数中,调用 createPlayerService 函数来创建播映器服务器,该函数在同级目录下的 mac源码编辑器hine.ts 中界说了,中心思路是经过给定时器 timer 参与需求实施的快照动作 actions , 在调用 timer.start() 初步回放快照。

export function createPlayerService() {json格局
//...
play(ctx) {
// 获取每个 event 实施的 doAction 函数
for (cons仓鼠养殖八大忌讳t event of needEven超神兽宠店ts) {
//..
cjson怎样读onst castFn = ge长生十万年tCast源码编辑器Fn(event);
actijsonpons.push仓鼠寿数({
doAction: () => {
castFn();
}
})
//.陈涉世家翻译及原文html标签.
}
// 增加到定时器部html是什么意思队中
thtml代码imer.addActions(actions);
// 建议定时器播映 视频
timer.start();
},
//.html..
}

播映服务运用到java环境变量装备第三方库 @xsta超神兽宠店te源码编辑器/JSONfsm 状况机来控制各种状况(播映,暂停源码网,直播)

定时器 timer.ts 也是在同级目录下,中心json怎样读是经过 requestAnimationFrame 完毕了定时器功用, 并对快照html标签回放,以部队的方法存储需求播映的超崇高骑士快照 actions ,接着在 star长生十万年t 中递归调用 action.doAction 来完毕对应时刻节源码年代点的快照康复。JSON

exjsjsonon格局怎json是什么意思样翻开port class Tim源码编辑器er {
// 增json是什么意思加队html
public adjson格局json格局怎样翻开dActions(actions: a陈思思ctihtml是什么意思onWithDelajavascripty[]) {
this.act源码分享网ions = this.actions.concat(actijava编译器ons);
}
// 播映部队
public start() {
function check() {
// ...
// 循环调用actions中的doAction 也就是 castFn 函数
whihtml5le (actions.lenjava怎样读gth) {
cons源码编辑器手机版下载t action = actions[0];
actions.shi源码网站ft();
// doAction 会对快照进行回放动作,针对json格局html代码怎样翻开不同快照会实施不同动作html标签特色大全
action.html个人网页完好代码doActihtml标签on();
}
if (源码超市action源码编辑长沙师范学院s.length > 0 || self崇圣寺三塔.liveMode) {
self.raf = requestAnimationFrjavaeeame(check);
}
}
this.raf = requestAnim源码年代ationFrame(check);
}
}

doAction 在不同类型快照会实施不同动作,在播映服务中 doAcjava面试题tion 究竟会调用 getCastFn 函数来做了一些 case:

priva源码之家te getCHTMLastFn(event: eventWithTime, isSync = false) {
swjava模拟器itjson格局怎样翻开ch (evjava怎样读ent.tjson转mapype) {
casHTMLe EventType.DomContentLoaded: //dom 加载解析完毕
case EventType.超崇高骑士FullSnapshot: // 全量快照
case EventType.IncrementalSnapshot: //增量
castFn = () => {
this.applyIncrementajava面试题l(evjava环境变量装备ent, isSync);
}
}
}

applyIncremental源码本钱数会增对jsonp跨域原理不同的增量快照做不同处理,包括 DOM 增量, 鼠标交互,页面翻滚等,以DOM 增量快照的 cjavascriptase 为例,究竟会走到 applyMutatihtml标签on中:

private applyIncrhtml代码emental(){
switch (d.CSSsource) {
case Incremehtml个人网json解析页无缺代码ntalSource.Mutation: {
this.applyMutation(d, isSync); // Djava根本数据类型OM改动陈涉世家翻译及原文
break;
}
case IncrementalSource.MouseMove: //鼠标移动仓鼠养殖八大忌讳
case Incrementaljson是什么意思Source.Mousjson怎样读eInteraction: //鼠源码之家标点击作业
//...
}

applyMuta仓鼠寿数tion 才是究竟实施 DOM 康复操作的当地,包括 DOM 的增修改过程:

prjsonivHTMLate applyMutation(d: mutationData, useVirtualParent: boolean) {
d.removes.forEach((mutation) => {
//.. 移除dom
});
const appendNode = (mutajava根底知识点tion: addedNodeMutation) => {
// 增加dom到详细节json解析点下
};
d.adds.forEachhtml网页制造((mutation)html个人网页完好代码 => {
//html 增加
aphtml5pendNode(mutation);
});jsonp
d.texts.forhtml5Each((mutation) => {
//..源码编辑器手机版下载.文本处理
});
d.ajava根本数据类型ttributes.forEachtml简略网页代码h((mutatijson格局怎样翻开on) => {
//.html标签..特征处理
});
}

以上就是回放的要源码集市害流程完毕代码,rrweb 中不仅仅是做了这些,还包括数据压缩,移动端处理,隐私问题等等细节处理,有喜欢可自行查看源码。

最终

这种HTMLHTML束录制回放思路的确值得学习,读 rrweb 源码的进程也获益颇多,源码中对数据结构的一些运用,例如双链表,部队,树等也值得一javaee览。

以上就是本次同享的全部内容,期望对你有所帮忙 ^_^

喜欢的话别忘了动动手指,点赞、超神兽宠店保藏、重视三连一波带走。


关于咱们

咱们是java编译器万拓科创前仓鼠寿数端团队,左手组件库,右手东西库,各种技术粗野生长。

一个人跑得快,不如一群人跑得远。欢源码本钱迎参与咱们的小分队,源码网站牛年牛气轰轰崇圣寺三塔往前冲。

参考文章

  • rrweb-io/rrwejsonb
  • rhtml是什么意思rweb:翻开 web 页源码编辑器编程猫下载json怎样读面录制与回放的黑盒子