BRUCE BLOG / INTERACTION

距离,不是时间:一次终端滚动排查

七轮排查都没有解释“不跟手”。直到我们开始比较,同一段手指位移究竟让画面走了多远。

杨永安 + Claude Code · 发布于 · 原始记录

“不跟手”还不是一个诊断

最初的反馈是:在 Bruce 终端里滚动全屏 TUI,惯性滚动很流畅,手指频繁上下往复时却觉得沉。对照是熟悉的 IDE 终端。我们很快把问题理解成了响应慢,于是开始量延迟。

这篇整理自 2026 年 9 月的开发记录。文中的数值属于当时的设备、版本和测试场景,不是对所有终端或机器的性能承诺。真正值得留下的是,如何把一个准确的体感描述,变成可以区分原因的测量。

数字都不错,为什么手感仍然不对

我们依次检查写入、传输、程序回包、终端解析、渲染帧率和字形图集。确实找到了可以改进的地方:更短的合并窗口、更合适的调度方式,以及不让阻塞写入拖住其它工作的处理。但这些改动都没有解释那个稳定的“沉”。

另一个问题是测量对象。浏览器里的最小页面、刚启动而没有内容的 TUI,和用户正在操作的原生窗口,是不同的现场。我们给实际窗口补上了可请求求值、返回结果的开发调试通道,才看清一次手势到底走了哪条路径。

那次追踪发现,眼前滚动的是终端自己的回滚缓冲,事件根本没有经过我们一直优化的“把滚轮报告交给程序”那条路。先确认手势归谁处理,应该发生在优化之前。

转折来自一个更朴素的对照

用户在另一款终端里做了同样的动作,给出更精确的描述:不是等得太久,是走得不够远。时间和距离终于被分开了。一个没有明显延迟的系统,也能因为位移增益不对而显得迟钝。

当时记录的一次三秒手势有 165 个事件,总位移约 1002px,平均每个事件约 6.1px。相关路径在把像素换算为行数时,对小于 50px 的事件额外乘了 0.3。触控板把手势切成许多小步,几乎每一步都被缩短。按当时约 15px 的行高估算,本该产生约 66 份报告,实际只有约 20 份。

影响的是交给全屏程序的滚轮报告,而不是所有滚动。两条路径混在一起测,延迟曲线再漂亮,也无法说明行程是否正确。

修复必须落在对应的路径上

第一版补偿用错了地方:把本来正常的回滚缓冲也放大,反而产生过冲。后来才把判断收窄到三个条件:事件会送给程序、使用像素模式、原始位移落在会被缩短的范围内。下面只保留当时判断的核心。

这不是把灵敏度统一调大。大步进的鼠标事件没有经过相同的缩短,不能一起放大。我们也把相同总位移、不同事件分片方式的结果整理为回归用例,并在当时向上游提交了问题与修复建议;本地行为仍需要独立验证。

const sensitivity = toProgram && pixelMode && Math.abs(deltaY) < 50
  ? configured / 0.3
  : configured;

让下一次排查少绕一点路

这次排查留下的,不只是滚动补偿。能进入实际窗口的调试通道、会报告失败的测量脚本,以及对照同一手势的习惯,都能帮助后来的开发者和 Agent 避免把正确的数字用在错误的对象上。

  • 先确认事件属于哪块表面、哪条处理路径。
  • “跟手”同时涉及时间和位移,两个量都要检查。
  • 记录设备、版本、内容和前台状态,让数字有明确出处。
  • 把决定性的对照写成回归用例,避免只留下“感觉好了”。

下载 Markdown