Skip to content

Latest commit

 

History

History
49 lines (29 loc) · 2.63 KB

File metadata and controls

49 lines (29 loc) · 2.63 KB

性能与内存优化 — 产品思考

技术实现见 docs/handover/performance-memory.md

解决了什么用户问题

长对话卡顿

CodePilot 的典型使用场景是持续数小时的开发会话,一次对话可能有 100+ 条消息、数百次工具调用。在 v0.45.0 之前:

  • 代码高亮器缓存无上限,200+ 个不同语言/主题组合后内存占用显著增长
  • 消息列表无上限,500+ 条消息时 DOM 节点数导致滚动卡顿
  • 终端输出(npm install 等)累积到几 MB 后渲染变慢
  • 图片引用 Map 随批量生成任务无限增长(已加 50 条上限 + 最老条目淘汰)

用户反馈集中在"用了两三个小时后 app 变慢了",但很难复现(因为依赖于具体的对话内容和工具调用模式)。

大文件预览崩溃

打开文件树时如果目录中有大文件(日志、数据文件),文件预览 API 会整文件读入内存。100MB+ 的文件直接导致 Node.js OOM。

为什么这样设计

LRU 而非定期清理

定期清理(如每 N 分钟扫描一次)有两个问题:清理间隔内仍然可能膨胀;清理时可能删掉刚用到的缓存导致闪烁。LRU 是自然的上限策略——缓存大小恒定,最近使用的自然保留。

消息列表 300 条硬上限

实测 300 条消息 + 工具调用 + 代码高亮大约对应 50-80MB 的 DOM 占用,在主流设备上流畅滚动。超出后的双向修剪策略确保用户无论是翻历史(prepend)还是继续对话(append)都不会超限。

reconciliation 机制解决了修剪后的数据一致性——流式完成时从 DB 重新加载,确保消息顺序和内容正确。但错误/停止状态跳过 reconciliation,因为此时可能有未持久化的临时消息(如流中断产生的 error 消息)。

stream-session-manager 定时器追踪

定时器泄漏是 Electron 应用的常见内存问题——每次对话创建的 setTimeout 如果不清理,回调中引用的 stream 对象永远不会被 GC。用 Set 集中管理比分散 clearTimeout 更可靠。

效果

没有做精确的内存基准测试(难以标准化测试场景),但根据用户反馈:

  • 长对话(3h+)后的明显卡顿消失
  • 文件预览不再因大文件崩溃
  • 首屏加载速度有感知提升(面板懒加载)

已知局限

  • 消息上限 300 是经验值,没有做设备适配(低端设备可能需要更低上限)
  • Shiki LRU 10 个 highlighter 可能对多主题切换场景不够(切主题会导致 cache miss 重建)
  • 文件流式读取的 line_count 是估算值,文件树显示的行数可能不精确