[Bug] 多会话切换明显卡顿:实测切换连接 P90 890ms / 峰值 8.6s,伴随高频 IPC 轮询与级联加载
Open
Nobody has claimed this yet.
priority: P2
- Dominant language
- No language data
- Stars
- 22
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
使用环境
- 客户端:ZCode Desktop 3.11.2
- 系统:Windows 11 x64
- 样本:本机 2026-09-05 单日运行日志(
~/.zcode/v2/logs/2026-09-05.log)与会话索引库(~/.zcode/v2/tasks-index.sqlite)统计,数据截至当日 17:49
问题描述
右侧同时管理 30+ 个会话(来自不同项目/任务)来回切换时,切换动作经常伴随明显卡顿:点开一个会话后,对话区要等几十毫秒到数秒才出内容,极端情况接近 9 秒。会话越多、单会话内容越长,越明显。
对当天日志做了统计,卡顿不是主观感受,而是结构性的:
| 指标 | 实测值 |
|---|---|
会话切换连接(v4 conversation store connect completed,n=390)P50 / P90 / P99 / Max |
52.5ms / 889.6ms / 5269ms / 8577ms |
| 超过 1 秒的切换占比 | 38/390 ≈ 9.7% |
zcode-agent.subscribeConversationV4 单次最大 |
8565.3ms(全天 391 次调用) |
zcode-agent.conversationPlansV4 单次最大 |
15255.9ms(572 次) |
zcode-agent.sendConversationCommandV4 单次最大 |
15853.7ms(336 次) |
zcode-session.readWorkspaceState 单次最大 |
12563.7ms(16 次) |
window-controller.listTaskList 全天调用 |
73423 次(平均约 1.2 次/秒) |
dropped buffered outbound payloads |
418 条日志 / 累计丢弃 469 个 payload |
stale renderer instance for sender |
161 次 |
| tasks-index.sqlite 主库 / WAL | 5.13MB / 4.35MB |
tasks 表 searchable_text |
135 行,单条最大 153239 字符,全表合计约 251 万字符 |
复现步骤
- 侧边栏管理 30+ 个会话,其中若干为长会话(几十条消息、含工具调用与文件变更);
- 在这些会话之间来回切换;
- 观察切换后对话区出内容的等待时间;同时看日志中
v4 conversation store connect completed的durationMs分布。
症状拆解(均可在日志中对应)
- 切换握手重、连接完成瞬间请求风暴:切换会话时 unsubscribe→subscribe 成对出现(当日各约 390 次),
subscribeConversationV4单次最长 8.5s;连接完成后,conversationFileChangesV4(1269 次)/conversationRowsRangeV4(1715 次)/conversationPlansV4(572 次)等重载请求集中倾泻,形成级联加载。 - listTaskList 高频轮询缺节流:全天 73423 次、平均约 1.2 次/秒,焦点切换或任务更新时 1 秒内连打多次;IPC 通道拥塞时日志出现
dropped buffered outbound payloads(418 条)与stale renderer instance(161 次)。 - 会话索引库行宽:tasks 主表把聊天全文塞进单行
searchable_text(实测单条最大约 15.3 万字符),高频 listTaskList 反复把大文本读入内存页;5.1MB 主库伴随 4.35MB WAL,写放大明显。 - 遥测链路放大:客户端内置
@arms/rum-electron与@opentelemetry/api,对上述高频 RPC 做全量 Span 包装,进一步抬高 CPU 与 GC 开销。
期望行为 / 工程建议
listTaskList增加节流/防抖与增量刷新(任务状态变化推送代替轮询,或至少合并高频请求);- 切换订阅握手异步化:先渲染轻量骨架/最近视口投影,plans / fileChanges 等重载分批或按需拉取,避免连接完成瞬间的请求风暴;
- tasks 表
searchable_text拆出 FTS5 虚拟表,列表查询只取标题与摘要; - 遥测对高频 RPC 降采样。
关联
- #488 / #422:同一「多会话切换」场景下的滚动定位问题。切换级联阻塞(峰值 8.6s)期间,定位/跟随逻辑可能未执行或被打断,两者或互为因果,建议一并排查。
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the 30+ session workload and inspect ~/.zcode/v2/logs/2026-09-05.log alongside tasks-index.sqlite. Trace listTaskList polling and the subscribeConversationV4 request sequence, using the reported latency, dropped-payload, and stale-renderer metrics as baselines. Because several possible causes and fixes are listed, done should include an isolated scope and before/after measurements showing faster switching without regressions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, sqlite
- Domain
- databases, desktop, performance
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100