Tiptap / ProseMirror 协作问题
✍️ 聚焦编辑器事务、Selection、NodeView、Schema 与多人协作同步中的复杂问题。
常见症状
- 光标跳动、丢失或无法移出自定义节点
- 输入法组合阶段重复提交或内容错乱
- NodeView 更新后 DOM 与文档状态不一致
- 撤销重做破坏远端内容
- 多人同时编辑出现重复、丢字或位置偏移
- 重连后文档状态与服务端不一致
分层理解
- Schema:节点、Mark、属性和内容约束
- State:文档、Selection、Stored Marks、插件状态
- Transaction:每次变更及其 metadata
- View / NodeView:状态到 DOM 的映射
- Collaboration:步骤或 CRDT 更新的传播与合并
排查证据
- 记录 transaction 的 steps、selection、meta 与时间戳
- 保存变更前后的文档 JSON
- 区分本地输入、插件追加事务和远端更新
- 检查 NodeView 的
update、ignoreMutation、stopEvent - 在中文输入法、粘贴、撤销、拖拽场景分别复现
高频根因
- 直接操作 DOM,未通过 transaction 更新文档
- NodeView 错误忽略 Mutation 或拦截事件
- 使用过期位置,异步后未重新映射 position
- Schema 或扩展顺序在客户端之间不一致
- 协作模式下混用了不兼容的历史记录方案
- 重连和初始化重复应用同一份更新
修复原则
- 以编辑器状态为事实来源,不从 DOM 反推业务状态
- 跨 transaction 保存位置时使用 mapping 或重新解析
- 协作客户端使用一致的 Schema、扩展和版本
- 对远端更新、初始化和重连设计幂等流程
- 自定义 NodeView 明确内容 DOM、事件边界和销毁逻辑
回归矩阵
- 中文输入法组合输入
- 光标进出节点与跨节点选择
- 粘贴、拖拽、撤销和重做
- 两端同时编辑同一位置
- 离线编辑后重连
- 不同网络延迟与重复消息
- NodeView 销毁后监听器已释放