DirectSurface UIDirectSurface UI
开始使用
文档/企业架构

大文档编辑

大文档编辑的核心目标不是一次性处理全部内容,而是让用户当前看到和正在编辑的区域保持稳定、快速、可预测。DirectSurface UI 中的大文本编辑器和病历编辑器都应遵循这个原则。

性能目标

大文档场景下,交互复杂度应接近:

可视区域节点 + 当前编辑边界复杂度

不应在鼠标移动、光标闪烁、拖选或单字符输入时扫描全部文档、全部页或全部 render tree。

三条主线

大文档优化通常分三条线:

  • 虚拟绘制:只绘制可视区域和少量缓冲区。
  • 增量排版:只重排变化节点附近内容,能 patch 就不全量分页。
  • 输入隔离:textarea 只作为输入承接,不承载整份文档内容。

这三条线要同时成立。只优化绘制但每次输入仍全量排版,用户仍会感觉卡顿。

输入策略

隐藏输入控件应只承接当前输入事件。粘贴几十 MB 文本时,应在 paste 事件中读取剪贴板数据并阻止浏览器把大文本落入 textarea。中文输入结束后也应尽快清空承接控件,避免浏览器对超大 value 做布局和选择计算。

对大文本编辑器来说,光标命中、选区更新和绘制都应该只访问可视行和必要索引。对病历编辑器来说,拖选和绘制应使用全局范围坐标投影到可视页,而不是展开整份文档选区树。

病历编辑器的页面接入、工具栏、批注留痕、打印和释放要求见 病历编辑器接入

排版策略

病历类文档需要分页。输入字符时可以先尝试快速 patch:

  • 当前段落或当前局部结构重新测量。
  • 如果高度和分页边界不变,替换当前 render。
  • 如果高度变化,再从变化位置向后修正分页。
  • 后续可扩展为分批异步排版,但当前可视区域必须优先稳定。

快速 patch 的判断不应只限制纯文本变更。最终判断标准是当前变化能否在局部 render 层面被稳定替换。

绘制策略

绘制只处理可见内容:

  • 大文本编辑器只绘制可视行。
  • 病历编辑器只绘制可视页和缓冲页。
  • 留痕块和批注块只布局可见相关项。
  • 光标闪烁只触发必要绘制,不能触发布局。

如果性能浮层显示持续 layout,应优先排查组件在 performLayout 中重复设置子组件状态,例如每次 layout 都创建新数组或调用会标记布局的方法。

内存策略

大文档关闭后,控制器、页面上下文、图片缓存、弹层、输入承接控件和事件订阅都要释放。缓存应按归属放在文档上下文或页面上下文,不要无理由放入全局。

内存验证建议:

  1. 打开大文档。
  2. 执行输入、滚动、弹层、批注等操作。
  3. 关闭页面或销毁应用实例。
  4. 生成 heap snapshot。
  5. 查找是否仍有页面、控制器、大数组或 canvas 被引用。

大文档优化必须同时看耗时和内存。只有绘制快但关闭后不释放,长期使用仍然会失控。