跳到主要内容

Tiptap / ProseMirror 协作问题

✍️ 聚焦编辑器事务、Selection、NodeView、Schema 与多人协作同步中的复杂问题。

常见症状

  • 光标跳动、丢失或无法移出自定义节点
  • 输入法组合阶段重复提交或内容错乱
  • NodeView 更新后 DOM 与文档状态不一致
  • 撤销重做破坏远端内容
  • 多人同时编辑出现重复、丢字或位置偏移
  • 重连后文档状态与服务端不一致

分层理解

  1. Schema:节点、Mark、属性和内容约束
  2. State:文档、Selection、Stored Marks、插件状态
  3. Transaction:每次变更及其 metadata
  4. View / NodeView:状态到 DOM 的映射
  5. Collaboration:步骤或 CRDT 更新的传播与合并

排查证据

  • 记录 transaction 的 steps、selection、meta 与时间戳
  • 保存变更前后的文档 JSON
  • 区分本地输入、插件追加事务和远端更新
  • 检查 NodeView 的 updateignoreMutationstopEvent
  • 在中文输入法、粘贴、撤销、拖拽场景分别复现

高频根因

  • 直接操作 DOM,未通过 transaction 更新文档
  • NodeView 错误忽略 Mutation 或拦截事件
  • 使用过期位置,异步后未重新映射 position
  • Schema 或扩展顺序在客户端之间不一致
  • 协作模式下混用了不兼容的历史记录方案
  • 重连和初始化重复应用同一份更新

修复原则

  • 以编辑器状态为事实来源,不从 DOM 反推业务状态
  • 跨 transaction 保存位置时使用 mapping 或重新解析
  • 协作客户端使用一致的 Schema、扩展和版本
  • 对远端更新、初始化和重连设计幂等流程
  • 自定义 NodeView 明确内容 DOM、事件边界和销毁逻辑

回归矩阵

  • 中文输入法组合输入
  • 光标进出节点与跨节点选择
  • 粘贴、拖拽、撤销和重做
  • 两端同时编辑同一位置
  • 离线编辑后重连
  • 不同网络延迟与重复消息
  • NodeView 销毁后监听器已释放