Skip to content

fix(desktop): bound nested rich-answer tab rendering - #7506

Open
king1uc wants to merge 1 commit into
makecindy:mainfrom
king1uc:fix/windows-streaming-hang-7491
Open

king1uc wants to merge 1 commit into
makecindy:mainfrom
king1uc:fix/windows-streaming-hang-7491

Conversation

@king1uc

@king1uc king1uc commented Oct 27, 2026 •

Copy link
Copy Markdown

这次改了什么

摘要

Desktop 的富回复标签页已经预先渲染了子节点,但在构建 tabpanel 时又递归渲染一次。每多一层 tabs,叶节点的 Markdown/媒体处理工作量翻倍;一个只有 10 层 tabs 和 1 个 Markdown 节点的合法回复会调用正文 renderer 1,024 次。现在 tabpanel 复用首次生成的子节点,每次更新只处理每个叶节点一次。

变更类型

  • fix 缺陷修复

范围

  • 关联 Issue / 需求:Refs Windows: main window Not Responding while assistant reply is streaming #7491。不关闭该 issue:本 PR 修复的是已独立复现的指数级渲染缺陷,尚未证明它解释报告中的 Windows 整窗未响应。
  • 本 PR 包含:Desktop 嵌套 tabs 的重复遍历修复;流式追加、结束和隐藏标签页输入状态的回归测试。
  • 明确不包含:主进程/IPC/数据库行为、Mobile renderer、应用安装或发布。
  • 用户可见变化:深层标签页不再随层数成倍增加正文处理;隐藏面板仍保持挂载,切换与已编辑值保持原有行为。
  • 是否存在 breaking change:无。

UI 变化

  • 引用的设计规范:不涉及:只复用已经生成的 React 子节点,不改变可见 DOM、样式、文案或标签页选择规则;输入及面板挂载行为由生产组件测试守护。

怎么验证的

自动验证

Windows 11,Node 24.12.0,pnpm 10.33.2;依赖通过 frozen lockfile 完整安装。

从 apps/desktop 执行:

node ../../node_modules/vitest/vitest.mjs run src/renderer/components/chat/__tests__/RichAnswer.test.tsx --maxWorkers=1
红灯:新增遍历测试预期 1 次,实际 1024 次;其余原有 11 项通过。
修复后:12/12 通过(测试执行 341ms,整个 Vitest 进程 7.66s)。

node ../../node_modules/vitest/vitest.mjs run src/renderer/components/chat/__tests__/RichAnswer.test.tsx src/renderer/__tests__/streamingProjectionPerformance.test.ts src/renderer/__tests__/streamingDerivedRender.test.tsx src/renderer/__tests__/streamingWorkGroupRender.test.tsx --maxWorkers=1
结果:4 文件、30/30 项通过;测试执行 5.06s,完整进程 67.91s(含 Windows 转换/收集开销)。
RichAnswer.test.tsx:13/13,790ms。

git diff --check
结果:通过。

类型检查:以 Desktop 原 tsconfig 为基础,include 限定这两个变更文件及 Desktop 原有的全部 *.d.ts;真实依赖仍由 TypeScript 正常递归解析,无 stub、无新增类型豁免。node --max-old-space-size=4096 node_modules/typescript/bin/tsc --noEmit -p outputs/fix-7491/tsconfig.rich-answer.json 退出码 0。

测试价值(RichAnswer.test.tsx,两项 Tier 1 生产组件测试):

  • 原测试只覆盖平面控件/内容,没有约束嵌套容器的遍历次数。11 节点输入在旧实现中稳定失败,不靠耗时阈值;同一断言还覆盖 streamed append 和 complete。
  • 额外面板测试覆盖真实点击、隐藏面板中的编辑值、流式 patch 和 DOM 输入节点身份,防止用卸载隐藏面板的方式绕过性能缺陷。结果不得抹去用户编辑或重建输入。

手工验证

未修改正在运行的安装版 Cindy。独立回归测试在 Windows 上挂载真实 RichAnswer 组件;没有声称完成 Electron 实机卡死复现或修复验收。

未执行的验证

  • Desktop 全量 typecheck 已尝试,但其内存占用约 8GB,检查期间观察到系统换页压力,主动暂停;以通过的较小范围检查补充本地验证,完整检查仍需 CI。
  • 无视觉变化,未生成截图。未运行完整整仓测试、Mobile 验证。
  • Windows: main window Not Responding while assistant reply is streaming #7491 报告的普通文字流式生成导致整窗“未响应”仍需调用栈/运行时复现定位;本修复不可作为整项故障已解决的证据。

风险

风险分类

  • 无已知风险

影响与回滚

  • 影响范围:Desktop 富回复 tabs 的 React 节点构造;没有数据、协议、权限、原生配置或存量插件兼容变化。
  • 回滚 / 降级方式:revert 本提交即可;无数据迁移。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名
  • UI 代码路径已说明不涉及视觉变化的原因
  • 未提交凭证、令牌或授权文件
  • 已核对受影响的文档;无需修改现有行为约定
  • 已确认测试结果并说明未完成验证

CI follow-up (2026-10-29)

client-ci attempt #2 is failed, not green. Both verify-checks and Linux unit tests (3/4) stopped during pnpm install --frozen-lockfile, before code verification/tests: ERR_PNPM_ENOENT, renaming a temporary directory under node_modules/@esbuild-kit/core-utils/node_modules/ to esbuild. The aggregate verify then failed because those jobs failed. All four Windows unit shards, their aggregate check, the Windows runner/database checks, Desktop Git integration, and the other three Linux unit shards succeeded. This PR changes only RichAnswer and its regression tests, with no dependency, lockfile, installer or CI changes.

The later main run succeeded, including verify-checks and all Linux/Windows shards, using the same pnpm 10.33.2 and unchanged .npmrc. This supports an installation issue; it does not make this PR's failed checks pass. A targeted failed-job rerun was attempted once, but GitHub rejected it with 403 Must have admin rights to Repository. A repository maintainer must rerun failed jobs; this contributor cannot clear the red checks. No unrelated code change, skipped assertion, or dummy commit was added to bypass the failure. Existing local validation and runtime limitations above remain unchanged.

Signed-off-by: WangTao <wangtao2@xd.com>
@king1uc
king1uc marked this pull request as ready for review October 29, 2026 10:00
@king1uc
king1uc requested a review from a team as a code owner October 29, 2026 10:00
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T10:04:45.389996Z a66643e Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] 本 PR 看起来可以安全合并,未发现由这些改动引入的实际问题。

Summary

本 PR 让 Desktop 富回复的标签页复用已生成的子节点,避免嵌套标签页重复递归渲染。

  • Nested rich-answer tabs render each child only once per update.

Reviews (1) · Last reviewed commit: "fix(desktop): bound nested rich-answer t..." · Reviewed by Greptile

@MagicLizi MagicLizi added the touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) label Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants