Skip to content

标注输入卡顿与启动阶段 CPU 断档诊断 ​

背景 ​

Owner 2026-11-02 在内部包 237 上连续录了两场目标 App A 的会话(设备 A,iOS 26),反馈 CPU 曲线断数据,并在第二场复测后判断“点击标注后数据就断了”。同日 Owner 指定 Claude 负责全项目修改与优化(兼任 Lead 与 Implementation,见 AGENTS.md),本批诊断与修复由 Claude 决策并实施。

证据(E3,会话原件) ​

两场均为采集完成状态:线路序号 0 缺口、0 重复、0 乱序,两条连接无错误、无重连。断档出现在采集进程收到 sysmontap 数据的时刻上,不是电脑端丢弃。

会话时长标注保存时刻整机 CPU 来源间隔 > 1.5 秒activitytrace 逐帧来源试探期
第一场≈29 秒第 16.9 秒2.6 秒起 2.8 秒;5.4 秒起 1.7 秒0–8.3 秒
第二场≈22.5 秒第 12.9 秒3.3 秒起 3.1 秒;6.4 秒起 2.1 秒;8.8 秒起 2.3 秒0–13.1 秒
10-30 有 3 次标注的会话≈87 秒33.6 / 61.3 / 81.0 秒无0–4.4 秒
10-30 无标注的三场≈52–55 秒无最多一次 1.6–1.7 秒0–3.6~4.1 秒
  • 第二场所有断档都发生在标注保存之前;试探期一结束,积压的 sysmontap 数据在约 9 秒内以正常两倍速率集中补到。
  • 第二场电脑端队列(Supervisor 入队→Controller 出队)在标注保存前 6 秒内出现 737 / 95 / 761 / 625 毫秒等待,其余样本约 0.2–0.6 毫秒,说明输入标注期间主线程被占用。
  • 两场的帧耗时来源都没有选出(第一场 primary-insufficient-evidence,第二场 resource-limited),逐帧统计只覆盖启动后约 1.2–1.6 秒。

判断 ​

  1. 已证实(E3):输入标注时主线程长时间被占用。代码中标注草稿 noteText 是整个工作台根视图的 @State,每输入一个字(含输入法拼字)都会使 2700 余行的工作台连同实时图表全部重算;这是界面“停住”的直接原因。
  2. 已证实(E3):落盘数据里的 CPU 断档来自采集进程侧,与启动/逐帧追踪试探期重合;标注本身不写入采集进程,10-30 的三次标注都没有引起断档。
  3. 待证(假设):本机为 4 物理核 Intel 笔记本,启动追踪连接在会话中传输 0.2–3 GB 数据;试探期的追踪解码与界面重绘可能共同占满 CPU,使 sysmontap 读取落后。标注输入是否会加重采集侧断档,需要 A/B 复测才能定论,不写成结论。

本批实现 ​

文件修改
MacApp/Sources/PerfowlApp/PerfowlWorkbenchView.swift新增私有子视图 NoteComposer,草稿文字状态移入其中;根视图只保留弹窗开关,提交后通过闭包调用原有 appendNote 并关闭弹窗。输入、提交、空白禁用与无障碍标识均保持不变。
  • 复杂度:每次按键的重算范围从整个工作台缩小到弹窗内一个文本框与按钮,与会话长度和图表数量无关。
  • 未改采集链路、指标公式与标注落盘格式。

验证 ​

  • swift build --product Perfowl 通过(E2)。
  • 前后对比基准:以 host-queue-timing.json 中输入标注期间的出队等待为指标,修复前为 625–761 毫秒;修复后需 Owner 在新包上复测(待 E3)。

遗留与下一步 ​

  • A/B 复测(Owner 操作):同一目标 App,各录约 60 秒;A 场全程不加标注,B 场在第 20 秒后(试探期结束后)打开标注框并输入约 10 秒。用于区分“启动试探期断档”与“标注输入加重断档”。
  • 启动/逐帧追踪试探期挤占 sysmontap:需要另立方案,方向包括给 sysmontap 独立读取优先级、限制试探期追踪数据量,以及让报告标明逐帧统计的实际覆盖时长。
  • 逐帧来源过滤未生效(请求 0x31800318,实际过滤列表为空)导致帧耗时整场缺失,单独立项。

Validation Update · 2026-11-02:内部包 238 构建与同址安装(E3) ​

  • 来源:main 1088df14,Developer ID 签名完整构建 203.6 秒,来源门禁 passed,包内提交号与 main 一致。
  • 校验:App 与 DMG 严格签名;冻结核心 107 个模块与 CLI 和源码一致;DMG 挂载、安装后文件树一致;安装后核心 probe ready。
  • 产物:MacApp/dist/Perfowl-238-macos-x86_64-internal.dmg,147,851,233 B,SHA-256 097a96a8a5c6964dde0d6d0804a4e7469d13c5bade6bacde3d6a037db4758509;237 安装包与回滚包移至私有归档并核对可恢复。
  • 启动器唯一:打包暂存目录改为 .noindex 并在安装后删除;LaunchServices 与 Spotlight 只剩 /Applications/Perfowl.app(首次按新规则实证)。
  • 未完成:公证按 Owner 内部测试边界暂缓(Gatekeeper exit 3、stapler exit 65);标注输入卡顿修复的效果与 A/B 复测待 Owner 在 238 上完成;未跑 Swift/Python 全量回归(本批只改一个 SwiftUI 视图)。

Validation Update · 2026-11-02:238 上 A/B 复测(E4,设备 A / 目标 App A) ​

Owner 在 238 上连续录 3 场:

会话时长标注每秒行进程 CPU/整机 CPU/内存缺值行(除首行预热)最大行间隔电脑端最大出队等待逐帧试探期sysmontap 来源间隔 > 1.5 秒
A≈190 秒无1900/0/01.08 秒28.2 毫秒0–4.6 秒0
B≈25 秒1 次260/0/01.06 秒60.2 毫秒0–3.6 秒0
C≈66 秒3 次660/0/01.02 秒25.2 毫秒0–3.7 秒0
  • 标注期间界面出队等待从修复前的 625–761 毫秒降到最多 60 毫秒;4 次标注前后 CPU、内存逐秒连续。
  • 逐帧试探期回到约 4 秒(与 10-30 一致),本轮没有出现启动阶段断档。237 两场试探期为何拉长到 8–13 秒、界面占用是否通过本机 4 核 CPU 竞争放大了采集侧断档,本轮无法单独证实,不写成结论;若再出现断档,按原件复查试探期时长与来源间隔。
  • 结论:标注导致的界面卡顿与 CPU 断档在本轮真机复测中未复现,标注修复验收通过(E4,3 场、4 次标注,单设备单目标 App)。帧耗时来源未选出、帧过滤未生效仍为开放项。

Perfowl · Performance Observer