本篇文章来自团队小伙伴 @陈小信 的一次学习同享,期望跟咱们同享与评论。
求积硅步致使千里,勇于探享日子之美。
问题布景
什么是前端录制回放?
望文生义,源码编辑器就是录制用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
改动进行监听以外,还有一个就是作业监听,用户与网页的交互多是经过鼠标,键盘等输入设备来进行。而这些交互的背面便Java是 JavaScript
的作业监听。作业监听能够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
包括三种状况:
- 可交源码java怎样读编辑器互
in源码编辑器编程猫下载terajson是什么意思ctive
;- 正在加载中
loading
;- 完毕
complete
takeFullSnapshot
从字面意思能看出其作用是生成「无缺」的快照,也就是会HTML将json格局怎样翻开 dojson格局cument
序列化出一个无缺HTML的数据,称之为 「全量快照」。
一切序列化相关操作都是运用 snapshot
完毕,snapshot
接受一个 dom
方针和一个装备方针传递 document
将整个页面java环境变量装备序列化得到完毕的快照数据。
// 生满足量快照
takeFullSnapshot = (isCheckout = false) => {
//...
const [node, idNodeMap] = snapshot(dojava编译器cument, {
//...一些装备项
});
//...
}html
idNodeMap 是一个
id
为key
,html标签特色大全DOM
方针为value
的key-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是什么意思b
将play
/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
和 装备HTML项 config
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播映器创建依靠 events
和 timer
,本质上仍是运用 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.ts
结html标签特色大全构函数中,调用 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
中不仅仅是做了这些,还包括数据压缩,移动端处理,隐私问题等等细节处理,有喜欢可自行查看源码。
最终
这种HTML结HTML束录制回放思路的确值得学习,读 rrweb
源码的进程也获益颇多,源码中对数据结构的一些运用,例如双链表,部队,树等也值得一javaee览。
以上就是本次同享的全部内容,期望对你有所帮忙 ^_^
喜欢的话别忘了动动手指,点赞、超神兽宠店保藏、重视三连一波带走。
关于咱们
咱们是java编译器万拓科创前仓鼠寿数端团队,左手组件库,右手东西库,各种技术粗野生长。
一个人跑得快,不如一群人跑得远。欢源码本钱迎参与咱们的小分队,源码网站牛年牛气轰轰崇圣寺三塔往前冲。
参考文章
- rrweb-io/rrwejsonb
- rhtml是什么意思rweb:翻开 web 页源码编辑器编程猫下载json怎样读面录制与回放的黑盒子