fix: restore the jump-to-bottom glide and keep user state, selections and scroll anchors in windowed lists

Pause scroll writes while the jump-to-bottom smooth scroll runs; keep rows with pending questions, approvals, recent interactions and selection ends mounted; cache Mermaid results; copy text spanning unmounted rows; anchor the sidebar on id changes; disable native overflow-anchor for windowed lists; write terminal output on the leading edge and before clear; forward remote events every 16 ms; flush streaming text before copy/export; add performance principle P10 (no UX regressions).
This commit is contained in:
mesalogo
2026-10-03 16:19:56 +08:00
parent a620c22676
commit 805acc3fce
25 changed files with 834 additions and 63 deletions
@@ -868,7 +868,7 @@ Renderer 主线程降速 4 倍(Main 不降速,每次 reload 后重新应用
### 7.2 按性能原则补齐差距(2026-10-03,第三轮并行)
统一标准见 `docs/architecture/performance-principles.md`(P1–P9、性能预算和评审清单)。本轮按其中“当前差距”并行推进:
统一标准见 `docs/architecture/performance-principles.md`(P1–P10、性能预算和评审清单)。本轮按其中“当前差距”并行推进:
| 原则 | 改动 | 测量结果 |
| --- | --- | --- |
@@ -893,6 +893,25 @@ Renderer 主线程降速 4 倍(Main 不降速,每次 reload 后重新应用
本轮回归:`perf:app` 60 项阈值全部通过(不降速,流式和流式打字长任务均为 0);typecheck、全量 lint 通过;全量测试中 2 个失败分别为 OpenCode 免费额度 403 的集成用例和 `magic-notes-*` 真实 Electron 测试在整套并行负载下的偶发失败,后者单独运行和 6 个 Electron 布局测试并行连跑 3 次均通过。
### 7.3 体验倒退复查(2026-10-03)
逐一复查了所有性能提交对交互体验的影响,并新增原则 P10“体验不倒退”。发现并修复:
| 问题 | 来源 | 修复 | 验证 |
| --- | --- | --- | --- |
| “到底部”按钮的平滑滚动动画消失,直接跳到底部 | `fdf7d83` 消息窗口化:贴底跟随、ResizeObserver、锚定修正都会瞬间写入 `scrollTop`,打断平滑滚动;点击时还立即切换窗口导致可见行被卸载 | 滑动期间暂停所有滚动写入,只随视口重新窗口化;到达底部、`scrollend` 或 1.5 秒兜底时再贴底;用户滚轮、按键或点击会接管滚动 | 真实 Electron 逐帧采样,要求有中间帧(旧代码中间帧为 0),连跑 3 次通过;新增单元测试,旧代码失败 |
| 消息滚出可见区后丢失状态:待回答问题里已选的选项和输入的内容、展开的工具详情和推理、Mermaid 重新绘制并显示“加载中” | `fdf7d83` | 有待回答问题或待审批的行、用户交互过的最近 8 行、选区两端所在的行保持挂载;Mermaid 按“主题 + 源码”缓存渲染结果(最多 64 个) | 单元测试,旧代码失败 |
| 跨多条消息选择文本时,选区起点被卸载;复制时只拿到已挂载的文字 | `fdf7d83` | 选区两端所在的行保持挂载;复制时,未挂载的消息用原文补全 | 单元测试 |
| 侧栏在上方插入、删除、置顶或 5 秒重排时,可见的会话行跳动 | `663aa85`,窗口化关闭了原生滚动锚定 | 会话 id 变化时,在绘制前按第一条可见行恢复位置;列表在顶部时不锚定 | 单元测试,旧代码失败 |
| 笔记、文件树、知识库文档表格的锚定修正可能和浏览器原生锚定冲突 | `b2eb86a` | 窗口化状态下关闭 `overflow-anchor` | 单元测试 |
| 终端打字回显多等一帧;点击“清屏”前到达的输出在清屏之后才显示 | `f4458af` | 空闲时立即写入,只合并同一帧内后续到达的输出;清屏前先写完待写入的输出 | 单元测试 |
| 远程 Runtime 流式输出最多 50 ms 一批,显示一顿一顿 | `d859cbf` | 合并间隔改为 16 ms;写库成功后立即转发,仍然是先写库再转发 | 单元测试 |
| 流式输出时从侧栏复制或导出会话,可能缺最后不超过 250 ms 的文字 | PERF-13 流式缓冲 | 复制、导出前先把待同步的流式文字刷进状态 | 单元测试,旧代码失败 |
检查后没有问题:CSS 动画和过渡没有被删改;其余 `scrollIntoView` 的行为和原来一致;标题跑马灯、侧栏 5 秒重排的悬停冻结、重命名和菜单行保持挂载;输入框自动增高;Markdown 和 KaTeX 渲染结果。快速大跨度跳转是否出现空白帧也做了实测:在 `perf:app` 滚动场景中加了检查,CPU 降速 4 倍时 10 次跳转中空白帧为 0,所以没有改动。
已知限制(不是倒退,原来也没有):读屏软件的浏览模式访问不到未挂载的消息;应用本身没有页内查找功能。
修复记录:文件树窗口化最初以 `.assistant-sidebar__body` 为滚动容器,但真实布局中滚动的是停靠的 `.workspace-files__files-view`,真实 Electron 测试发现后改为优先使用后者。
### PERF-14 状态