位置
apps/web/src/hooks/useGlobalAgentListeners.ts:330(MESSAGE_APPENDED 分支)
apps/web/src/hooks/runtime-event-state.ts:174-182(sameRuntimeEvents 短路判断)
问题
每条落盘消息(user/assistant/tool,一个 turn 2-3 条)触发 GET_THREAD_RUNTIME_EVENTS 全量拉取,走 hydrateRuntimeEvents。其短路判断 sameRuntimeEvents 对两数组逐 index 比 JSON.stringify(a) === JSON.stringify(b)——persisted 侧全部是 IPC 反序列化新对象,引用比较必然 miss,全部落入慢路径。
2000 上限的会话(delta 合并后仍含 assistant.final 全文双份)单次为数 MB 字符串序列化,主线程阻塞数十至数百 ms,随会话长度线性恶化。这是「累积慢化」专项 / PR#109 的同类残留:#109 修了无界增长,没修比较成本。
建议
短路改用廉价指纹(length + 尾事件 id + updatedAt)判断是否有变化;或让 sidecar 支持 afterSeq 增量返回。
位置
apps/web/src/hooks/useGlobalAgentListeners.ts:330(MESSAGE_APPENDED分支)apps/web/src/hooks/runtime-event-state.ts:174-182(sameRuntimeEvents短路判断)问题
每条落盘消息(user/assistant/tool,一个 turn 2-3 条)触发
GET_THREAD_RUNTIME_EVENTS全量拉取,走hydrateRuntimeEvents。其短路判断sameRuntimeEvents对两数组逐 index 比JSON.stringify(a) === JSON.stringify(b)——persisted 侧全部是 IPC 反序列化新对象,引用比较必然 miss,全部落入慢路径。2000 上限的会话(delta 合并后仍含 assistant.final 全文双份)单次为数 MB 字符串序列化,主线程阻塞数十至数百 ms,随会话长度线性恶化。这是「累积慢化」专项 / PR#109 的同类残留:#109 修了无界增长,没修比较成本。
建议
短路改用廉价指纹(length + 尾事件 id + updatedAt)判断是否有变化;或让 sidecar 支持 afterSeq 增量返回。