Skip to content

perf(desktop): reduce composer typing work - #1236

Merged
MagicLizi merged 2 commits into
makecindy:mainfrom
hushaowu-rh:perf/desktop-composer-typing
Aug 1, 2026
Merged

perf(desktop): reduce composer typing work#1236
MagicLizi merged 2 commits into
makecindy:mainfrom
hushaowu-rh:perf/desktop-composer-typing

Conversation

@hushaowu-rh

@hushaowu-rh hushaowu-rh commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

降低 Desktop composer 普通打字期间的 React 重渲染、布局读取、草稿序列化和历史投影开销:普通 Tiptap transaction 留在编辑器内部,仅在 palette trigger 或空/可发送状态变化时刷新 React;caret scroll 合并到一个可取消 RAF;草稿 JSON 序列化与写入 debounce,并在生命周期边界 flush;assistant 流式更新期间复用稳定的用户历史数组。

本轮根据 review 修复了语音输入异步停止/润色期间切换 session 时的草稿串写:延迟任务执行前重新确认其 storage key 仍属于当前 editor,避免把新 session 内容写入旧 session 草稿;同时完成两项已验证的 render gate 与 history projection 清理。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:Mac Desktop composer 偶发输入卡顿定位与优化
  • 本 PR 包含:Tiptap transaction render gate;caret-scroll RAF 合并;草稿保存 debounce/flush;语音输入 session-switch 草稿隔离;稳定用户历史投影;相关回归测试
  • 明确不包含:同步 Ghost IPC 移除(由独立 PR fix(desktop): remove composer ghost sync IPC #1235 处理);composer 视觉设计调整
  • 用户可见变化:打字和 assistant 流式输出期间应减少卡顿;现有输入、palette、发送、草稿和历史行为保持不变
  • 是否存在 breaking change:无

UI 变化

不涉及:修改的是 composer 内部更新调度、持久化时序与对象身份,无布局、样式、交互规则或文案变化,因此无截图/录屏可提供。

  • 引用的设计规范:不涉及:未改变 UI 布局、样式、交互或文案,仅优化内部 transaction、RAF 与草稿保存调度

怎么验证的

自动验证

pnpm --dir apps/desktop exec vitest run \
  src/renderer/lib/__tests__/composerDraftSessionSwitchGuard.test.ts \
  src/renderer/lib/__tests__/composerDraftSaveScheduler.test.ts \
  src/renderer/components/new-chat/__tests__/composerRenderGate.test.ts \
  src/renderer/components/new-chat/__tests__/composerFrameScheduler.test.ts \
  src/renderer/components/new-chat/__tests__/composerHistoryProjection.test.ts \
  src/renderer/__tests__/composerDraftMountRace.test.ts \
  src/renderer/__tests__/chatInputSessionFocus.test.ts \
  src/renderer/__tests__/chatInputSteerShortcut.test.ts \
  src/renderer/__tests__/composerQuotePaletteBoundary.test.ts
结果:9 个文件、33 个测试通过

pnpm --dir apps/desktop exec eslint <本 PR 本轮修改的 5 个文件>
结果:通过

pnpm --dir apps/desktop typecheck
结果:通过

pnpm check:dco
结果:2 个 commit 均通过 DCO

git diff --check
结果:通过

手工验证

本轮未进行 production build 的交互 benchmark;无视觉变化需要截图验收。

未执行的验证

  • 尚未完成真实 macOS production build 的 p50/p95 transaction-to-next-frame benchmark,因此不在本 PR 中声称已测得具体性能提升幅度。
  • pnpm test:unit 已尝试,但 Desktop Vitest 在当前 macOS/Node 环境的 threads pool 中发生原生 SIGSEGV;forks pool 的诊断运行可继续,仅遇到与本 PR 无关的 BillingPage.test.tsx 固定日期断言失败。未删除、跳过或弱化测试来制造通过。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:renderer 更新与草稿保存时序

影响与回滚

  • 影响范围:Desktop composer 的 React refresh、caret scroll、内存草稿保存和用户历史投影;草稿属于 best-effort 内存状态,不影响已发送消息
  • 回滚 / 降级方式:回退本 PR 的两个 commit 可恢复原 transaction/render/save 行为;语音 session-switch guard 可独立回退,但会重新暴露旧 session 草稿被新 session 内容覆盖的风险

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

🤖 Generated with Claude Code

Signed-off-by: Shao-Wu Hu <271197399+hushaowu-rh@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 31, 2026 14:39
@hushaowu-rh
hushaowu-rh requested a review from a team as a code owner July 31, 2026 14:39

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7e16a55083

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/renderer/components/new-chat/ChatInput.tsx

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves desktop ChatInput/composer performance by reducing React re-renders and coalescing layout- and persistence-heavy work during Tiptap editor updates, while keeping user-history identities stable during assistant streaming.

Changes:

  • Introduces render gating so ChatInput only re-renders when trigger/palette state or sendable/empty state changes.
  • Coalesces caret scrolling to a single cancellable animation frame instead of scheduling many independent frames.
  • Debounces draft serialization/writes with explicit flushes at lifecycle boundaries, and stabilizes user history projections across streaming updates.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
apps/desktop/src/renderer/lib/composerDraftSaveScheduler.ts New debounced scheduler to coalesce draft save work and support flush/cancel.
apps/desktop/src/renderer/lib/tests/composerDraftSaveScheduler.test.ts Unit tests for draft save scheduler behavior (latest-task wins, flush, cancel, defaults).
apps/desktop/src/renderer/components/new-chat/composerRenderGate.ts New snapshot-based gate to decide when editor activity should trigger a React render.
apps/desktop/src/renderer/components/new-chat/composerHistoryProjection.ts New stable projection to avoid re-allocating user history arrays when only assistant rows change.
apps/desktop/src/renderer/components/new-chat/composerFrameScheduler.ts New RAF scheduler that coalesces/cancels pending caret-scroll frames.
apps/desktop/src/renderer/components/new-chat/ChatInput.tsx Integrates render gating, coalesced caret scrolling, debounced draft saving + lifecycle flushes, and stable history projection.
apps/desktop/src/renderer/components/new-chat/tests/composerRenderGate.test.ts Unit tests covering the render gate decision logic.
apps/desktop/src/renderer/components/new-chat/tests/composerHistoryProjection.test.ts Unit tests validating stable history identity and correct projection updates.
apps/desktop/src/renderer/components/new-chat/tests/composerFrameScheduler.test.ts Unit tests for the coalesced requestAnimationFrame scheduler.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/desktop/src/renderer/components/new-chat/composerRenderGate.ts
@greptile-apps

greptile-apps Bot commented Jul 31, 2026

Copy link
Copy Markdown

Greptile Summary

This PR reduces composer work during typing while preserving draft and navigation behavior.

  • Gates React refreshes on palette-trigger and empty/sendable-state changes.
  • Coalesces caret scrolling into a cancellable animation frame.
  • Debounces draft serialization and flushes pending saves at lifecycle boundaries.
  • Reuses user-history projections while only assistant messages are streaming.
  • Adds focused regression tests for the new schedulers, render gate, history projection, and session-switch guard.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
apps/desktop/src/renderer/components/new-chat/ChatInput.tsx Integrates gated editor refreshes, coalesced caret scrolling, debounced draft persistence, lifecycle flushes, and stable history projection.
apps/desktop/src/renderer/components/new-chat/composerRenderGate.ts Compares the complete palette-trigger snapshot and empty/non-empty state before requesting a React refresh.
apps/desktop/src/renderer/lib/composerDraftSaveScheduler.ts Implements latest-task draft-save debouncing with synchronous flush and cancellation support.
apps/desktop/src/renderer/components/new-chat/composerFrameScheduler.ts Coalesces repeated caret-scroll requests and supports teardown cancellation.
apps/desktop/src/renderer/components/new-chat/composerHistoryProjection.ts Preserves user-history array identity when assistant-only streaming updates do not alter user entries.

Sequence Diagram

sequenceDiagram
    participant User
    participant Editor as Tiptap Editor
    participant Gate as Render Gate
    participant React as ChatInput React Tree
    participant Frame as Caret Frame Scheduler
    participant Draft as Draft Save Scheduler
    participant Store as Draft Store

    User->>Editor: Type or move selection
    Editor->>Gate: Compare trigger and empty state
    alt Relevant snapshot changed
        Gate->>React: Refresh composer controls
    else Ordinary transaction
        Gate-->>React: Skip parent refresh
    end
    Editor->>Frame: Schedule caret scrolling
    Frame->>Frame: Replace pending frame
    Frame-->>Editor: Scroll caret on next frame
    Editor->>Draft: Schedule latest draft save
    Draft->>Draft: Coalesce updates for 120 ms
    alt Timer fires
        Draft->>Store: Serialize and save latest document
    else Blur, send, session switch, or unmount
        Draft->>Store: Flush pending save synchronously
    end
Loading

Reviews (2): Last reviewed commit: "fix(desktop): guard composer draft sessi..." | Re-trigger Greptile

@MagicLizi

Copy link
Copy Markdown
Contributor

@hushaowu-rh 👋 这个 PR 还有 3 条 review conversation 没 resolve(apps/desktop/src/renderer/components/new-chat/ChatInput.tsx / apps/desktop/src/renderer/components/new-chat/composerRenderGate.ts / apps/desktop/src/renderer/components/new-chat/composerHistoryProjection.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

格式门未通过

PR description 缺少以下必要段落(参照 .github/PULL_REQUEST_TEMPLATE.md):

  • 这次改了什么(What)
  • 怎么验证的(Test Plan)
  • 风险(Risks)

请补齐上述段落后更新 PR description。

@MagicLizi

Copy link
Copy Markdown
Contributor

本 PR 命中 UI 路径(apps/desktop/src/renderer/components/new-chat/ChatInput.tsx 等)但 description 未附界面效果证据。建议补充改动后效果:截图/录屏,或说明纯逻辑改动无视觉变化。

此提醒不阻断合并,仅供参考。

@MagicLizi

Copy link
Copy Markdown
Contributor

⏸️ 本 PR 触发白名单确认门(product:命中 UI 路径)。

放行名单成员在本 PR 上 Approve 即放行;需修改请 Request Changes。

讨论 issue 见上方链接。

讨论 issue:#1256

Signed-off-by: Shao-Wu Hu <271197399+hushaowu-rh@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 1, 2026 05:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在「待确认 PR」面板完成维护者确认。

@MagicLizi

Copy link
Copy Markdown
Contributor

白名单确认门已放行(product,由 MagicLizi 确认),PR 恢复正常推进。

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查通过,零 P0/P1。性能优化结构清晰:render gate + RAF 合并 + draft 节流 + session 切换守卫,测试覆盖到位。

@MagicLizi
MagicLizi merged commit dee3b3c into makecindy:main Aug 1, 2026
5 of 6 checks passed
@MagicLizi

Copy link
Copy Markdown
Contributor

合并了,composer 打字体验显著改善——render gate + draft 节流这套组合拳很漂亮。

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.

3 participants