rrweb-snapshot
概述
将 DOM 快照为带有状态且可序列化的数据结构, 并提供通过快照重建 DOM 的能力。
API
本模块导出以下方法:
snapshot
snapshot 会遍历 DOM,并返回一个带有状态且可序列化的数据结构,用于表示当前 DOM 的视图。
快照过程中会完成以下几件事:
- 将部分 DOM 状态内联到 HTML 属性中,例如 HTMLInputElement 的 value。
- 将 script 标签转换为
noscript标签,以避免脚本被执行。 - 尝试内联样式表,确保本地样式表可以被使用。
- 将 href、src 和 CSS 中的相对路径转换为绝对路径。
- 为每个节点分配一个 id,并在快照完成时返回 id 与节点的映射表。
rebuild
rebuild 会根据已拍摄的快照构建 DOM。
在浏览器环境中,rebuild() 是一个底层 API,除非传入 UNSAFE_allowUnprotectedRebuild: true,否则它要求使用由 rebuildIntoSandboxedIframe() 创建的 document。不可信的回放数据不得直接重建到顶层 document 或调用方自行创建的 iframe document 中。
在浏览器中使用时,优先选择 rebuildIntoSandboxedIframe:
rebuildIntoSandboxedIframe 要求显式传入 root 元素。
const { iframe, node } = rebuildIntoSandboxedIframe(snapshot, {
root: document.body,
cache,
mirror,
});如果需要单独管理 iframe,请在调用 rebuild() 之前使用 createSandboxedIframe() 创建它。
如果你明确接受脚本执行风险,可以向 rebuild 传入 UNSAFE_allowUnprotectedRebuild: true。
重建过程中会完成以下几件事:
- 如果节点是 Element,则添加 data-rrid 属性。
- 创建一些额外的 DOM 节点(如文本节点),用于放置内联 CSS 和部分状态。
- 如果节点包含额外的子 DOM,则添加 data-extra-child-index 属性。
serializeNodeWithId
serializeNodeWithId 可以将节点序列化为带 id 的快照格式。
buildNodeWithSN
buildNodeWithSN 会根据序列化节点构建 DOM,并将序列化信息存储在 mirror.getMeta(node) 中。
rrweb-snapshot 发布说明
2.1.1
本版本无变更,仅为与其他包保持版本同步而提升版本号
2.1.0
补丁变更
- #1865
b08a06f感谢 @eoghanmurray! - 修复当 URL 包含 hash 时,绝对地址转相对地址的转换问题
2.0.1
补丁变更
- #1854
5f52d63感谢 @eoghanmurray! - 修复网页被第三方库猴子补丁(monkey patch)修改后,Webkit/Safari 中 MutationObserver 失效的问题
2.0.0
重大变更
#1497
2606a2a感谢 @Juice10! - 分发文件采用了新的文件名、路径和扩展名。重要提示:如果你直接引用分发文件或类型,可能需要更新你的路径/文件名,例如你从rrweb/typings/...或rrdom/es导入。但如果你是通过import rrweb from 'rrweb'使用,则不会察觉到此变更带来的差异。 如果你直接在 script 标签中引入 rrweb 文件,可能需要将路径更新为对应的.umd.cjs文件。所有.js文件现在都使用 ES 模块,可在现代浏览器、node.js 以及支持 ES 模块的打包器中使用。所有 npm 包现在还同时提供.cjs和.umd.cjs文件。.umd.cjs文件是将所有文件打包在一起的 CommonJS 模块,便于向浏览器环境分发单个文件(类似于之前的.js文件)。.cjs文件是可在旧版 Node.js 环境中使用的 CommonJS 模块。类型在package.json中有了更完善的定义,如果你需要特定类型,它们可能从新的包中导出(例如PlayerMachineState和SpeedMachineState现在从@rrweb/replay导出)。请查看package.json的main和exports字段了解可用文件。#1834
43e4f5b感谢 @Juice10! - 默认要求浏览器中的rebuild()调用必须以rebuildIntoSandboxedIframe()或createSandboxedIframe()创建的 document 为目标。对于不可信的回放数据请使用这些辅助函数;仅在明确接受脚本执行风险时才传入UNSAFE_allowUnprotectedRebuild: true。rrweb现在将UNSAFE_replayCanvas重建标记为显式的不安全路径,因为 canvas 回放会向回放 iframe 添加脚本权限。#1593
5a78938感谢 @daibhin! -NodeType枚举已从 rrweb-snapshot 移至 @rrweb/types 以下类型已从 rrweb-snapshot 移至 @rrweb/types:documentNode、documentTypeNode、legacyAttributes、textNode、cdataNode、commentNode、elementNode、serializedNode、serializedNodeWithId、serializedElementNodeWithId、serializedTextNodeWithId、IMirror、INode、mediaAttributes、attributes和DataURLOptions#868
e4f680e感谢 @Juice10! - 移除INode/node.__sn的用法,改用Mirror作为唯一事实来源。
次要变更
#1432
123a81e感谢 @Juice10! - Video 和 Audio 元素现在还会捕获playbackRate、muted、loop、volume。#1503
335639a感谢 @Juice10! - 录制 dialog 的模态状态,以便在 rrweb 中回放。(目前 rrweb-snapshot 的 rebuild 不支持触发dialog.showModal())#1188
bc84246感谢 @benjackwhite! - feat:扩展 maskInputFn,将 HTMLElement 传递给决策函数#1152
eac9b18感谢 @mydea! - feat:忽略 video/audio 元素上的autoplay属性#1310
7c0dc9d感谢 @benjackwhite! - 扩展 maskTextFn,将 HTMLElement 传递给决策函数#1035
2a80949感谢 @Juice10! - 新增对跨域 iframe 录制的支持,包括事件/id 重映射以及genId导出支持。#989
3809060感谢 @YunFeng0817! - 新增对可构造样式表adoptedStyleSheets的录制与回放支持,包括样式表变更、replace/replaceSync、shadow root、iframe、实时模式以及虚拟 DOM 回放。
补丁变更
#1580
47a7c3f感谢 @guntherjh! - 处理调用 adaptCssForReplay 时 postcss 抛出的异常#1386
a2c8a1a感谢 @ababik! - 修复可选的maskInputFn在创建全量快照时被意外忽略的问题#1417
40bbc25感谢 @YunFeng0817! - fix:修复 style 元素 textContent 重复导致增量样式变更失效的问题#1762
22bc4c3感谢 @Juice10! - 从所有构建产物中移除 base64 内联的 worker 源码#1279
11f6567感谢 @eoghanmurray! - 扩展 fixBrowserCompatibilityIssuesInCSS,使其也处理内联样式表#1615
dc20cd4感谢 @eoghanmurray! - 提升 splitCssText 处理包含大量 CSS 内容的<style>元素时的性能——参见 #1603#1640
3e9e42f感谢 @eoghanmurray! - 提升 splitCssText 处理包含大量 CSS 内容的<style>元素时的性能——参见 #1603#1464
03b5216感谢 @colingm! - 更好地支持与修改内置Array.from函数的旧库(如 MooTools 和 Prototype.js)共存#1481
46f1b25感谢 @eoghanmurray! - 针对影响复杂 tailwind css 回放的 bug #1457 添加修复和测试#1476
cbbd1e5感谢 @eoghanmurray! - 修复多处 background-clip 替换的问题#1600
a6893f7感谢 @eoghanmurray! - #1575 修复 postcss 在处理被任意拆分的 CSS 内容时可能崩溃的问题#1133
c28ef5f感谢 @eoghanmurray! - 修复:CSS transition 在 Firefox 中重建时被错误应用的问题。推测原因是 Firefox 未能及时完成样式解析,从而对 CSS 中设置了非零 margin 且带有 transition 的元素应用了默认的 margin:0。Firefox 相关 bug 报告:https://bugzilla.mozilla.org/show_bug.cgi?id=1816672
#1387
5e7943d感谢 @H4ad! - 避免每次都重新创建相同的元素,改为缓存该元素并仅对其进行更新。优化前:779k ops/s 优化后:860k ops/s
#1468
4014305感谢 @eoghanmurray! - inlineImages:快照期间避免为同源图片的内联添加事件监听器(异步监听器会修改快照,可能导致问题)#1130
f6f07e9感谢 @AgentWrapper! - 修复:内联样式表时,让样式表 URL 的相对路径检测覆盖更多类型的 URL 协议。#1095
1385f7a感谢 @YunFeng0817! - 修复 shadow DOM 重复的问题#1705
f2419f2感谢 @megboehlert! - 使用 ownerNode.baseURI 来序列化样式表的 href#1440
c0f83af感谢 @daibhin! - 改进嵌套 CSS 选择器的拆分,正确处理引号文本中出现逗号或括号的情况#1467
e96f668感谢 @eoghanmurray! - #1434 性能优化后的 bug 修复:修复 blob URL 残留在共享的 anchor 元素上且之后无法修改的问题#1272
58c9104感谢 @eoghanmurray! - 性能:遍历样式规则时避免创建中间数组#1126
227d43a感谢 @YunFeng0817! - 将所有 CommonJS 模块打包脚本的后缀从 'js' 重构为 cjs #1087。#1493
82f6fec感谢 @eoghanmurray! - 回放:替换 CSS 解析器正则表达式中的负向回顾断言(negative lookbehind),因为它会在 Safari 16 中引发问题#1148
d0fdc0f感谢 @YunFeng0817! - 改进:为 snapshot.ts 的文本脱敏函数添加 try catch。修复 #1118。#1482
f3cf092感谢 @AlfieJones! -(当recordCanvas: true时):确保使用 doc.createElement 而非 document.createElement,以便在 jsdom 等非浏览器环境中使用#1351
a2be77b感谢 @eoghanmurray! - 当<textarea>已预填内容时,避免重复录制其值 #1301#1837
527d9d3感谢 @Juice10! - 从@rrweb/record构建产物中 tree-shake 掉仅用于回放的postcss代码。#1287
efdc167感谢 @Juice10! - 为 Chrome/Edge 的 CSS@import转义 bug 添加临时解决方案:https://bugs.chromium.org/p/chromium/issues/detail?id=1472259#1431
a7c33f2感谢 @eoghanmurray! - 确保 :hover 在回放器中生效,即使规则位于媒体查询之内 遵循 max-device-width 和 min-device-width 媒体查询的意图,使其效果在回放器环境中得以体现#1614
6f4e691感谢 @billyvg! - 改为忽略所有 link[rel="modulepreload"],而不仅是带有as="script"的项#1535
04ee6ed感谢 @eoghanmurray! - 对 #1458 之后 :hover 的替换方式做小幅简化#1437
5fbb904感谢 @eoghanmurray! - 边界情况:支持对(罕见地)包含多个文本节点的<style>元素进行变更处理#1533
d350da8感谢 @jeffdnguyen! - 修复嵌套样式表的url()重写问题,改为在字符串化过程中重写,而非在之后重写#1512
d08624c感谢 @eoghanmurray! - 优化:跳过叶子元素的脱敏检查#1155
8aea5b0感谢 @YunFeng0817! - Feat:为序列化元素添加 'isCustom' 标记。该标记用于表示元素是否为自定义元素,有助于回放自定义元素的 :defined 伪类。
#1374
314a8dd感谢 @andrewpomeroy! - 捕获标记为rel="preload"的样式表#1731
76df979感谢 @eoghanmurray! - 修复 #1705 之后缺失的导入#1349
07ac5c9感谢 @eoghanmurray! - 文本脱敏时的快照性能:避免在递归遍历 DOM 时重复调用closest#1704
33e01f5感谢 @eoghanmurray! - 在 /dist/ 之外提供 /umd/ 输出目录,以便提供带 .js 扩展名的 UMD(Universal Module Definition)文件,同时不违背 package.json 中 /dist/ 下所有 .js 文件均为模块的约定#760
e08706a感谢 @eoghanmurray! - 新增 slimDOM 选项以屏蔽<title>标签上的动画;当 slimDOM 使用 'all' 值时启用#1509
be6bf52感谢 @Juice10! - 对内置方法进行反向猴子补丁,以支持 LWC(以及其他会对内置方法打猴子补丁的框架,如 angular)。#1047
9bbc3e0感谢 @Juice10! - 序列化 CSS 规则时保留-webkit-background-clip: text。#1012
6f44bb7感谢 @Juice10! - 确保回放插件的onBuild钩子对新追加的变更节点和顶层重建的 document 节点都会运行。#995
55ebce7感谢 @YunFeng0817! - 修复延迟内联样式表链接的回放:改为更新现有 link/style 节点的属性,而不是添加子节点。#970
23e3a73感谢 @Juice10! - 在普通属性之后应用内部rr_*属性,使rr_dataURL等仅用于回放的值不会被序列化的 DOM 属性覆盖。#927
fd85c79感谢 @Juice10! - 通过正确处理负数和未序列化的节点 id,修复 iframe 重新加载和 rrdom diff 问题。#984
6eaec04感谢 @QuentinLowe! - 修复第二次全量快照之后 iframe 回放失败的问题。#994
a9a2559感谢 @wfk007! - 通过在 mirror 中跟踪被忽略的节点,修复使用slimDOMOptions时丢失变更的问题。#938
f3064c1感谢 @lele0108! - 修复 SVG<use href="#...">的快照序列化,使本地片段引用被保留,而不是被转换为绝对 URL。#942
f03504a感谢 @YunFeng0817! - 修复对由 ShadyDOM 和@lwc/synthetic-shadow提供 polyfill 的 Shadow DOM 的录制与回放。#944
f1b23dd感谢 @YunFeng0817! - 修复快进回放,使通过虚拟 DOM 路径重建时 iframe 内的 canvas 图像数据能够被恢复。
2.0.0-alpha.19
补丁变更
#1580
47a7c3f感谢 @guntherjh! - 处理调用 adaptCssForReplay 时 postcss 抛出的异常#1615
dc20cd4感谢 @eoghanmurray! - 提升 splitCssText 处理包含大量 CSS 内容的<style>元素时的性能——参见 #1603#1640
3e9e42f感谢 @eoghanmurray! - 提升 splitCssText 处理包含大量 CSS 内容的<style>元素时的性能——参见 #1603#1600
a6893f7感谢 @eoghanmurray! - #1575 修复 postcss 在处理被任意拆分的 CSS 内容时可能崩溃的问题#1705
f2419f2感谢 @megboehlert! - 使用 ownerNode.baseURI 来序列化样式表的 href#1614
6f4e691感谢 @billyvg! - 改为忽略所有 link[rel="modulepreload"],而不仅是带有as="script"的项#1731
76df979感谢 @eoghanmurray! - 修复 #1705 之后缺失的导入
2.0.0-alpha.18
重大变更
- #1593
5a78938感谢 @daibhin! -NodeType枚举已从 rrweb-snapshot 移至 @rrweb/types 以下类型已从 rrweb-snapshot 移至 @rrweb/types:documentNode、documentTypeNode、legacyAttributes、textNode、cdataNode、commentNode、elementNode、serializedNode、serializedNodeWithId、serializedElementNodeWithId、serializedTextNodeWithId、IMirror、INode、mediaAttributes、attributes和DataURLOptions
补丁变更
#1535
04ee6ed感谢 @eoghanmurray! - 对 #1458 之后 :hover 的替换方式做小幅简化#1437
5fbb904感谢 @eoghanmurray! - 边界情况:支持对(罕见地)包含多个文本节点的<style>元素进行变更处理
2.0.0-alpha.17
次要变更
- #1503
335639a感谢 @Juice10! - 录制 dialog 的模态状态,以便在 rrweb 中回放。(目前 rrweb-snapshot 的 rebuild 不支持触发dialog.showModal())
补丁变更
#1417
40bbc25感谢 @YunFeng0817! - fix:修复 style 元素 textContent 重复导致增量样式变更失效的问题#1533
d350da8感谢 @jeffdnguyen! - 修复嵌套样式表的url()重写问题,改为在字符串化过程中重写,而非在之后重写#1509
be6bf52感谢 @Juice10! - 对内置方法进行反向猴子补丁,以支持 LWC(以及其他会对内置方法打猴子补丁的框架,如 angular)。
2.0.0-alpha.16
补丁变更
#1386
a2c8a1a感谢 @ababik! - 修复可选的maskInputFn在创建全量快照时被意外忽略的问题#1512
d08624c感谢 @eoghanmurray! - 优化:跳过叶子元素的脱敏检查
2.0.0-alpha.15
重大变更
- #1497
2606a2a感谢 @Juice10! - 分发文件采用了新的文件名、路径和扩展名。重要提示:如果你直接引用分发文件或类型,可能需要更新你的路径/文件名,例如你从rrweb/typings/...或rrdom/es导入。但如果你是通过import rrweb from 'rrweb'使用,则不会察觉到此变更带来的差异。 如果你直接在 script 标签中引入 rrweb 文件,可能需要将路径更新为对应的.umd.cjs文件。所有.js文件现在都使用 ES 模块,可在现代浏览器、node.js 以及支持 ES 模块的打包器中使用。所有 npm 包现在还同时提供.cjs和.umd.cjs文件。.umd.cjs文件是将所有文件打包在一起的 CommonJS 模块,便于向浏览器环境分发单个文件(类似于之前的.js文件)。.cjs文件是可在旧版 Node.js 环境中使用的 CommonJS 模块。类型在package.json中有了更完善的定义,如果你需要特定类型,它们可能从新的包中导出(例如PlayerMachineState和SpeedMachineState现在从@rrweb/replay导出)。请查看package.json的main和exports字段了解可用文件。
补丁变更
#1468
4014305感谢 @eoghanmurray! - inlineImages:快照期间避免为同源图片的内联添加事件监听器(异步监听器会修改快照,可能导致问题)#1493
82f6fec感谢 @eoghanmurray! - 回放:替换 CSS 解析器正则表达式中的负向回顾断言(negative lookbehind),因为它会在 Safari 16 中引发问题#1482
f3cf092感谢 @AlfieJones! -(当recordCanvas: true时):确保使用 doc.createElement 而非 document.createElement,以便在 jsdom 等非浏览器环境中使用#760
e08706a感谢 @eoghanmurray! - 新增 slimDOM 选项以屏蔽<title>标签上的动画;当 slimDOM 使用 'all' 值时启用
2.0.0-alpha.14
补丁变更
#1464
03b5216感谢 @colingm! - 更好地支持与修改内置Array.from函数的旧库(如 MooTools 和 Prototype.js)共存#1481
46f1b25感谢 @eoghanmurray! - 针对影响复杂 tailwind css 回放的 bug #1457 添加修复和测试#1476
cbbd1e5感谢 @eoghanmurray! - 修复多处 background-clip 替换的问题#1387
5e7943d感谢 @H4ad! - 避免每次都重新创建相同的元素,改为缓存该元素并仅对其进行更新。优化前:779k ops/s 优化后:860k ops/s
#1440
c0f83af感谢 @daibhin! - 改进嵌套 CSS 选择器的拆分,正确处理引号文本中出现逗号或括号的情况#1467
e96f668感谢 @eoghanmurray! - #1434 性能优化后的 bug 修复:修复 blob URL 残留在共享的 anchor 元素上且之后无法修改的问题
2.0.0-alpha.13
次要变更
补丁变更
2.0.0-alpha.12
次要变更
- #1310
7c0dc9d感谢 @benjackwhite! - 扩展 maskTextFn,将 HTMLElement 传递给决策函数
补丁变更
#1272
58c9104感谢 @eoghanmurray! - 性能:遍历样式规则时避免创建中间数组#1351
a2be77b感谢 @eoghanmurray! - 当<textarea>已预填内容时,避免重复录制其值 #1301#1431
a7c33f2感谢 @eoghanmurray! - 确保 :hover 在回放器中生效,即使规则位于媒体查询之内 遵循 max-device-width 和 min-device-width 媒体查询的意图,使其效果在回放器环境中得以体现#1155
8aea5b0感谢 @YunFeng0817! - Feat:为序列化元素添加 'isCustom' 标记。该标记用于表示元素是否为自定义元素,有助于回放自定义元素的 :defined 伪类。
#1374
314a8dd感谢 @andrewpomeroy! - 捕获标记为rel="preload"的样式表#1349
07ac5c9感谢 @eoghanmurray! - 文本脱敏时的快照性能:避免在递归遍历 DOM 时重复调用closest
2.0.0-alpha.11
补丁变更
#1279
11f6567感谢 @eoghanmurray! - 扩展 fixBrowserCompatibilityIssuesInCSS,使其也处理内联样式表#1287
efdc167感谢 @Juice10! - 为 Chrome/Edge 的 CSS@import转义 bug 添加临时解决方案:https://bugs.chromium.org/p/chromium/issues/detail?id=1472259
2.0.0-alpha.10
补丁变更
2.0.0-alpha.9
补丁变更
2.0.0-alpha.8
次要变更
- #1188
bc84246感谢 @benjackwhite! - feat:扩展 maskInputFn,将 HTMLElement 传递给决策函数
补丁变更
- #1148
d0fdc0f感谢 @YunFeng0817! - 改进:为 snapshot.ts 的文本脱敏函数添加 try catch。修复 #1118。
2.0.0-alpha.7
次要变更
补丁变更
2.0.0-alpha.6
次要变更
补丁变更
#1133
c28ef5f感谢 @eoghanmurray! - 修复:CSS transition 在 Firefox 中重建时被错误应用的问题。推测原因是 Firefox 未能及时完成样式解析,从而对 CSS 中设置了非零 margin 且带有 transition 的元素应用了默认的 margin:0。Firefox 相关 bug 报告:https://bugzilla.mozilla.org/show_bug.cgi?id=1816672
#1130
f6f07e9感谢 @Equlnox! - 修复:内联样式表时,让样式表 URL 的相对路径检测覆盖更多类型的 URL 协议。
2.0.0-alpha.5
补丁变更
#1095
1385f7a感谢 @YunFeng0817! - 修复 shadow DOM 重复的问题#1126
227d43a感谢 @YunFeng0817! - 将所有 CommonJS 模块打包脚本的后缀从 'js' 重构为 cjs #1087。