开发者最害怕的时刻莫过于:测试环境一切正常,一上线用户就报错。
更糟糕的是,用户反馈往往只有一句:'页面打不开了'或者'点击没反应'。当我们试图复现时,却发现自己无论怎么操作都无法触发 Bug。用户不愿意提供详细步骤,客服也传达不清楚,最后只能对着日志干瞪眼。
如果有这样一种技术,能像'时光倒流'一样,完整还原用户出错前的每一步操作,那该多好?
一、为什么我们需要监控与回放?
1.1 沉默的流失
在产品运营中,愿意主动上报 Bug 的用户是极少数。 绝大多数用户遇到体验问题或 Bug 时,选择是直接关闭页面,卸载应用,然后永远不再回来。我们失去了挽留他们的机会,甚至不知道他们为什么离开。
1.2 '在我这里没问题'
前端开发的口头禅:'我没复现这个问题啊,用户怎么操作的'。因为线上环境太复杂:
- 用户的网络波动
- 特定的浏览器版本
- 特殊的操作顺序
- 并发请求的竞争条件
1.3 解决方案:从'猜'到'看'
传统的日志监控(如 Sentry)只能告诉我们哪里错了(Error Stack),但很难告诉我们用户是怎么操作才导致错的。 会话回放技术填补了这个空白。
二、什么是 rrweb?
rrweb (record and replay web) 是一个开源的 Web 会话录制与回放库。
2.1 它不是视频录屏
很多人以为 rrweb 是像 OBS 一样录制视频流。这么想你就错了
- 视频录屏: 录制像素点,文件大,无法检索,无法分析 DOM 结构。
- rrweb 回放: 录制 DOM 变更事件(Mutation)。它记录的是'在什么时间,哪个节点,发生了什么变化'。
2.2 核心优势
- 体积极小: 传输的是 JSON 文本,经过压缩后,几分钟的操作可能只有几十 KB。
- 可检索: 因为记录的是 DOM 结构,你可以搜索页面上的文字来定位片段。
- 隐私可控: 可以在录制时配置忽略敏感输入框(如密码、银行卡号)。
- 跨平台: 录制的文件可以在任何地方回放,甚至离线回放。
三、核心原理:DOM 的序列化与反序列化
rrweb 的工作原理可以概括为:'把页面上的状态变成 JSON 数据,然后拿着这个 JSON 数据再转换成页面'。
3.1 录制阶段(Record)
rrweb 在用户浏览器中运行,主要依赖以下技术:
- MutationObserver: 监听 DOM 树的变化(节点新增、删除、属性修改、文本变化)。
- 事件监听: 监听鼠标移动、点击、滚动、输入等交互事件。
- 快照(Snapshot): 在录制开始时,通过遍历 DOM 树生成一份初始 HTML 结构的 JSON 快照。
- 增量数据: 之后只记录变化的部分(Incremental Data)。
数据流示例:
// 初始快照 { "type": 2, "data": { "node": { "tagName": "html", ... } } }
// 增量操作:用户点击了按钮 { "type": 3, "data": { "source": 1, "positions": [{ "x": 100, "y": 200 }] } }

