Skip to content

Stabilize ChatView and App callbacks to stop closure chains - #150

Merged
shaohaozhi286 merged 1 commit into
masterfrom
claude/stable-callbacks-chatview-app-20261019
Oct 19, 2026
Merged

shaohaozhi286 merged 1 commit into
masterfrom
claude/stable-callbacks-chatview-app-20261019

Conversation

@shaohaozhi286

Copy link
Copy Markdown
Collaborator

背景

#148 修掉了 Desktop 挂机 OOM 的主因(侧栏空闲渲染 + 闭包链)。之后实测发现,活跃使用(切换会话 + 状态变化)时 ChatView 与 App 仍在接链:依赖各不相同的 useCallback 在不同渲染里交替重建,V8 让同一次渲染的闭包共享一个作用域,旧回调把整份渲染作用域留住。

改动

  • ChatView 100 个、App 34 个依赖会变状态 / props 的回调改用 useStableCallback。
  • 保留 useCallback 的回调(测试里的 KEEP 表逐条写明原因):
    • ChatView 不随会话重新挂载,submit 等异步流程在 await 之后调用的会话绑定回调(草稿、输入历史、发送、上传、回填输入框、打开预览)共 10 个。若改成稳定引用,用户中途切会话时会作用到新会话上。
    • App 交给 usePreviewPresentation / useRef 的两个函数(渲染期间调用)。
  • 原先靠回调身份变化隐式重跑的 effect 显式补上依赖:聚焦、排队出队、tail-follow、变更面板收起、浏览器页签恢复、预览自动刷新。
  • 原先只检查侧栏的守卫测试换成 stableCallbacksArchitecture.test.js,覆盖 Sidebar / ChatView / App;源码锚点类测试同步更新。
  • CLAUDE.md「Desktop 挂机内存」一节更新了测量结果与三条边界。

验证

  • pnpm test 全量 3261 条通过,pnpm build 通过。
  • 隔离 daemon + 无头 Edge 堆快照对照,交替「切换会话 + 切换未读」160 次:ChatView 作用域存活从 262 份降到 17 份,App 从 176 份降到不再接链;操作翻倍到 320 次时 ChatView 也只有 21 份。
  • CDP 交互冒烟(输入、面板 / 控制台开关、切会话后草稿仍在、回首页再切回):无页面异常,也没有 console.error。
  • 未在 Desktop 实机上长时间挂机复测。

Session switches and status updates rebuilt ChatView/App callbacks with
different dependencies on alternating renders, so V8 kept every render's
scope alive through the shared closure context. Callbacks that depend on
changing state or props now use useStableCallback (ChatView 100, App 34).

- Keep useCallback where identity must follow the session: ChatView's
  async submit path calls draft/history/send/upload/preview helpers after
  an await, and ChatView does not remount per session (10 kept, reasons
  recorded in the test). App keeps the two functions handed to hooks.
- Effects that relied on callback identity to rerun now list the values
  they follow (focus, queue drain, tail-follow, change dock, browser tab
  restore, preview auto-refresh).
- Replace the Sidebar-only guard with stableCallbacksArchitecture.test.js
  covering Sidebar, ChatView and App; update source-anchor tests.

Measured with an isolated daemon and headless Edge (160 alternating
session switches / unread toggles): ChatView scopes retained 262 -> 17,
App 176 -> none.
@shaohaozhi286
shaohaozhi286 merged commit 3099953 into master Oct 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants