Skip to content

perf(review): 避免 Agent 工作时重复重建 Diff - #3591

Merged
DavidShenXD merged 1 commit into
mainfrom
cindy/epic-goodall
Aug 29, 2026
Merged

perf(review): 避免 Agent 工作时重复重建 Diff#3591
DavidShenXD merged 1 commit into
mainfrom
cindy/epic-goodall

Conversation

@DavidShenXD

Copy link
Copy Markdown
Collaborator

这次改了什么

摘要

修复审查界面展开多个 Diff 后,Agent 持续修改文件时整个 Desktop 严重掉帧、审查区域外操作也出现高延迟的问题。

本次包含三项针对性优化:

  1. Review 不再响应同一 Agent turn 内的每条 text/tool/usage stream 更新;仅在当前 turn 从 running 变为 stopped 后统一刷新,并在重新进入 running 或组件卸载时取消待执行刷新,避免陈旧 refresh 竞态。
  2. “最后一轮改动”筛选只在路径集合实际变化时更新 external-store snapshot,避免普通文本 stream 让 Review 组件树无效重渲染。
  3. 多个已展开 Diff 的累计非虚拟化行数超过阈值时,启用外层文件列表虚拟化并收紧 overscan;行数判断使用轻量计数,不预先分配完整 Diff row 对象。

变更类型

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

范围

  • 关联 Issue / 需求:bug: 打开侧边栏的 diff 审查界面会很卡顿 #3513
  • 本 PR 包含:Review 刷新触发、最后一轮文件筛选快照、展开 Diff 的外层虚拟化策略,以及对应行为单测。
  • 明确不包含:本地 trace 录制/分析脚本、压测夹具和原始 trace 文件。
  • 用户可见变化:Agent 工作且多个 Diff 已展开时,Desktop 操作明显更流畅;Agent turn 结束后统一显示最新 Diff。
  • 是否存在 breaking change:无。

UI 变化

无视觉、布局或文案变化;仅调整既有 Review 的后台刷新时机和大列表渲染策略。

  • 引用的设计规范:不涉及:未新增或修改视觉样式、布局、交互控件或 UI 文案。

怎么验证的

自动验证

pnpm test:unit:related
结果:通过

pnpm --filter desktop run --if-present typecheck
结果:通过

git diff --check
结果:通过

pnpm check:dco
结果:通过,1 个提交已签名

定向 Review 测试共 107 项,107/107 通过。独立 review 覆盖 running → stopped → running 延迟刷新竞态、重新 running 时取消待执行刷新、卸载清理及虚拟化阈值;未发现新的刷新或 callback 问题。

手工验证

在同一台 Windows 机器、同一 Dev Desktop/profile、同一任务下做双版本 trace。窗口为 1934×1229、165Hz,展开 21 个 Diff;每版采样 9 秒,执行 8 次 text stream,并对 6 个夹具文件各修改和恢复一次(共 12 次 apply_patch)。

指标 改动前(2310a133 改动后(95278ebf7
rAF p95 36.3ms 6.2ms
最大帧间隔 279ms 36.4ms
估算丢帧 927 10
主线程 Task 8269ms 1612ms
Script 3668ms 299ms
Style + Layout 1459ms 106ms
Paint + Composite(inclusive) 1935ms 413ms
Trace 长任务 42 0
Review DOM 25,771 8,493
DOM mutation 批次 29 0

结论:主要瓶颈是 stream 更新反复触发完整 Review 重建,Script 是最大成本,Paint/Layout 是完整重建带来的放大结果。优化后 Agent 运行阶段不再重复刷新整个 Review,结束时统一刷新;多个展开 Diff 的累计行数过大时由外层虚拟化限制常驻 DOM。该同机同场景 A/B 中,rAF p95 从 36.3ms 降至 6.2ms,Trace 长任务从 42 个降至 0。

未执行的验证

  • 未在 macOS/Linux 上重复录制性能 trace;本问题按用户实际出现环境在 Windows Dev Desktop 完成同机 A/B。
  • 未上传原始 trace:其中可能包含本机路径和任务元数据;PR 仅保留汇总指标和复现条件。
  • 未单独做 Light/Dark 目检:本次没有样式或色彩改动。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:Review 刷新时机变化。

影响与回滚

  • 影响范围:Agent 正在运行时,Review 不再随每条 stream 实时重载完整 Diff;当前 turn 结束后统一刷新。显式刷新和窗口 focus 刷新能力保留。
  • 回滚 / 降级方式:回退本 PR 提交即可恢复原有逐 stream debounce 刷新和文件列表虚拟化策略。

提交前检查

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

@greptile-apps

greptile-apps Bot commented Aug 29, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 优化 Desktop 审查界面的刷新和渲染策略,减少 Agent 流式工作期间重复重建 Diff。

  • 将 Git Review 自动刷新收敛到当前 Agent turn 的 running→stopped 边沿,并处理待执行刷新取消与卸载清理
  • 使用稳定的路径集合快照避免普通文本流触发“最后一轮改动”消费者重渲染
  • 根据已展开 Diff 的累计非虚拟化行数动态启用外层文件列表虚拟化,并通过轻量计数避免提前构造渲染行
  • 补充刷新边沿、路径快照和虚拟化阈值相关单元测试

Confidence Score: 5/5

未发现需要阻止合并的具体问题,此 PR 看起来可以安全合并。

刷新边沿、待执行刷新取消、路径快照稳定性及展开 Diff 行预算均有与实现一致的测试覆盖,调查中未确认可到达的功能、安全或数据正确性故障。

Important Files Changed

Filename Overview
apps/desktop/src/renderer/features/right-sidebar/plugins/review/useReviewGitState.ts 将 Review 的 store 驱动刷新限制为 Agent turn 结束边沿,并增加可取消 debounce 与卸载清理。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/useLastTurnFilter.ts 将 external-store snapshot 改为排序后的路径集合序列化值,使路径未变化的 stream 通知不再触发消费者重渲染。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/DiffViewer/diffRows.ts 新增与 unified/split 行构建逻辑一致的轻量行数统计,并扩展文件列表虚拟化判定。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/ReviewTabBody.tsx 根据展开且未自行虚拟化的 Diff 行数动态启用外层虚拟化,并在该场景下降低 overscan。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/tests/useReviewGitState.test.ts 覆盖 running→stopped 刷新、继续运行时取消待刷新及非运行通知不误刷新的行为。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/tests/useLastTurnFilter.test.ts 验证路径集合不变时不重渲染、路径集合变化时正确更新。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/tests/ReviewTabBody.helpers.test.ts 验证展开 Diff 行预算仅累计未自行虚拟化的文件,并在文件数已超阈值时跳过扫描。
apps/desktop/src/renderer/features/right-sidebar/plugins/review/DiffViewer/tests/PlainUnifiedDiff.test.ts 验证 unified/split 轻量计数与新增文件列表虚拟化阈值。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
    A[Agent turn running] --> B[忽略普通 stream 更新]
    B --> C{running 变为 stopped?}
    C -- 否 --> B
    C -- 是 --> D[Debounce Review 刷新]
    D --> E[重新加载 Git Diff]
    E --> F[统计已展开的 eager Diff 行]
    F --> G{累计行数超过阈值?}
    G -- 是 --> H[启用外层文件列表虚拟化]
    G -- 否 --> I[保持普通文件列表渲染]
Loading

Reviews (1): Last reviewed commit: "perf(review): 避免 Agent 工作时重复重建 Diff" | Re-trigger Greptile

@MagicLizi MagicLizi added status:ci-failed CI 失败(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) status:ci-running CI 还在跑(review-pr 自动维护,仅展示) and removed status:ci-failed CI 失败(review-pr 自动维护,仅展示) labels Aug 29, 2026
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

反馈已处理

已处理:

  • 已将 cindy/epic-goodall rebase 到最新 origin/main23870312)。
  • rebase 无冲突,原性能优化行为和提交范围保持不变。

变更:

  • 仅更新分支基线;提交 SHA 从 95278ebf7 更新为 3d4cbc5c
  • 已使用 --force-with-lease 推送 PR 分支,未覆盖其他人的远端提交。

验证:

  • pnpm test:unit:related:通过。
  • pnpm --filter desktop run --if-present typecheck:通过。
  • git diff --check:通过。
  • pnpm check:dco:通过,1 个提交签名有效。
  • 已确认最新 origin/main 是当前 PR head 的祖先。

备注:

  • 没有冲突需要人工处理。
  • GitHub 自动检查已由本次推送重新触发;未等待远端检查完成。
  • 未执行 merge。

@MagicLizi MagicLizi added status:ci-failed CI 失败(review-pr 自动维护,仅展示) status:ci-running CI 还在跑(review-pr 自动维护,仅展示) and removed status:ci-running CI 还在跑(review-pr 自动维护,仅展示) status:ci-failed CI 失败(review-pr 自动维护,仅展示) labels Aug 29, 2026
Signed-off-by: david <david@xd.com>
@DavidShenXD

Copy link
Copy Markdown
Collaborator Author

已再次同步最新 main055ad6555,其中包含 #3592 对 Codex 时序敏感测试的稳定性修复),并在 PR 分支完成 rebase。

  • rebase:无冲突
  • PR head:68a867ba3
  • 验证通过:pnpm test:unit:related
  • 验证通过:pnpm --filter desktop run --if-present typecheck
  • 验证通过:git diff --check origin/main...HEAD
  • 验证通过:pnpm check:dco

本地 trace/fixture 工具仍保留为未暂存文件,未进入 PR。新的 CI 已由本次推送触发,当前等待 GitHub 检查结果。

@DavidShenXD
DavidShenXD merged commit 5535037 into main Aug 29, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:ci-running CI 还在跑(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants