fix(rectification): stop re-parsing settled messages on every stream frame
Independent Staging Quality Gate / validate (push) Failing after 6m18s
Independent Staging Quality Gate / publish (push) Skipped

This commit is contained in:
jesse-ux
2026-09-16 07:13:12 +08:00
parent 53a37ce944
commit 58ccafb67c
25 changed files with 827 additions and 213 deletions
+16
View File
@@ -11269,3 +11269,19 @@
- 相关记录:BUG-059、BUG-388
- 复发自:BUG-059(总预算约束);BUG-388 的防复发只写了单次尝试,因此没拦住
- 修复版本:待发布
## BUG-725 | 校正会话流式时整条对话每帧重建,已结算消息每帧重跑 Markdown
- 状态:resolved
- 首次发现:2026-09-15
- 最近更新:2026-09-16
- 影响面:`rectification-agentic-chat.tsx` 消息列表、`chat-message-content.tsx` 结算态 Markdown、`chat-message-row.tsx`
- 用户现象:生时校正会话越长越卡,尤其在正在写出结果的那一轮。历史气泡跟着直播行一起抖。
- 触发条件:校正会话已有十余轮结算消息,再发一条会触发长流式回答。
- 根因:BUG-473 在本文件落地了 `stream-frame-buffer`(每帧最多提交一次),但校正面没有咨询面那套「已结算历史 / 正在流的那一条」记忆化边界。`messages.map` 内联派生时间轴、varga 句、选择题卡和 `afterAnswer``ChatMessageRow``memo`;结算态走 `renderProse` 全量 parse。每帧 `setMessages` 只替换直播行对象,但整张列表仍重渲,已结算行连同 Markdown 全部重算。同类前史:BUG-249(巨型容器每次击键全量重渲)。
- 修复:结算态 Markdown 复用 `StableMarkdownPrefix``memo` + 按文本的解析缓存);抽出 `RectificationMessageEntry``memo`),把逐消息派生搬进组件,回调经 `actionsRef` 更新 `.current``ChatMessageRow` 同样 `memo`。不把流式文本搬出 `messages`,不启用 React Compiler,不用 `React.lazy`+`Suspense` 承载 Markdown。
- 验证:`frontend/tests/rectification-settled-render-split.test.ts`(源码合同 + 按帧渲染计数:已结算行 4 次不随 5 个流式帧增长,未拆分对照 25 次);`chat-markdown-split.test.ts` 新增「同一段文本连续渲染两次,解析器只调用一次」(改前 2 次,改后 1 次)。改前该计数测试因模块不存在而红。咨询面既有 `home-streaming-render-split` / `chat-markdown-split` / `stream-frame-buffer` 无断言改动且全绿。
- 防复发:任何流式会话面都必须为已结算消息保留记忆化边界,并由一条按帧驱动的渲染计数断言钉死;新增会话面必须同时补这条断言。流式状态仍须经 `stream-frame-buffer` 提交;流式期间 Markdown 仍走前缀/尾块切分;结算态不得再走无缓存的整篇 parse。
- 相关记录:BUG-473、BUG-249、BUG-250、BUG-260、BUG-617
- 复发自:BUG-473(影响面含本文件,但两条防复发只约束正在流的那一行)
- 修复版本:待发布