外观
多会话汇总报告与截图条联动:产品设计
Owner 2026-11-02 提出:① 报告截图可用鼠标滚动/拖动查看,点击截图定位联动;② 历史会话支持多选,同一 App 多份报告汇总,形式与当前报告一致并支持导出。本文为 Claude(产品与实现负责人)的设计。
一、截图条
| 交互 | 设计 |
|---|---|
| 鼠标滚轮 | 上下滚轮在截图条上转为左右滚动;触控板横滑保持原样。 |
| 拖动 | 在截图条上按住拖动即左右平移(移动超过 4 pt 才算拖动,不影响单击)。 |
| 单击截图 | 游标定位到该截图时刻(曲线、右侧时刻详情同步),该截图高亮。 |
| 双击截图 | 放大查看(保持)。 |
| 曲线 → 截图 | 游标移动或固定时,截图条自动滚动到最近的截图(±2 秒内)并高亮。 |
二、多会话汇总报告
入口
- 历史测试列表顶部新增“多选”。进入多选后每行显示勾选框,只允许同一 Bundle ID:选中第一份后,其他 App 的行置灰并提示“只能汇总同一应用”。
- 底部操作栏:“已选 N 份 · 生成汇总报告”(2 ≤ N ≤ 20)、“取消”。只汇总状态为“测试已结束”的会话。
页面(与单份报告同一框架)
- 顶部:应用名、“汇总 N 份测试”、设备与系统(多种时列出全部并提示“设备/系统不一致,结果仅供参考”)、时间范围、总时长。
- 左侧分类:概览、启动、CPU 与调度、内存、画面表现、GPU、网络与磁盘、能耗(与单份报告相同)。
- 概览:
- 核心指标卡片:平均 FPS、静止秒数占比、Jank、BigJank、Stutter、1% Low FPS、应用 CPU、应用内存(均值/峰值)、总流量、启动耗时。每张卡片显示“汇总值”与“各次范围 最低–最高”,并注明“N/N 份有数据”。
- 会话对比表:每份一行(开始时间、时长、设备·系统、上述核心指标);每列最好值绿色、最差值红色;点击一行打开该份报告。
- 其他分类页:该分类每个指标一行——汇总值、最低、最高,以及各次数值。
汇总公式(先文档后代码)
记第 i 份会话:均值 m_i、有效样本数 n_i、帧统计窗口 T_i(秒)、每秒 FPS 秒数 s_i。
| 类型 | 指标 | 汇总值 |
|---|---|---|
| 采样均值 | 应用/整机 CPU、内存、GPU、网络速率、能耗等 | 合并均值 Σ m_i·n_i ÷ Σ n_i(等同把所有样本放在一起求平均) |
| 峰值 | 内存峰值等 | max |
| 累计 | 上行/下行/总流量 | Σ |
| 每秒 FPS | 平均 FPS、静止秒数占比、FPS≥18/25 | 按秒数加权 Σ v_i·s_i ÷ Σ s_i |
| 次数率 | Jank / BigJank / TinyJank / SmallJank(次/10分钟)、Drop、Delta | Σ (r_i·T_i) ÷ Σ T_i(总次数 ÷ 总时长) |
| 时长占比 | Stutter、FTime≥100% | 按窗口加权 Σ v_i·T_i ÷ Σ T_i |
| 帧耗时均值 | 平均帧耗时 | 按帧数加权(帧数不可得时按 T_i) |
| 不可合并 | 1% Low、中位数、方差、Smooth、P95 | 显示各次的中位数并标注“各次中位”,同时给出范围 |
| 单次事件 | 启动耗时 | 均值、中位、最低、最高 |
- 某份会话缺少某指标时,该指标只用有数据的会话汇总,并显示“k/N 份有数据”;不补 0。
- 每份会话的数值取自其已封存的报告(与单份报告一致),汇总不重新计算原始数据。
导出
- Excel(与单份报告同风格),三页:
- 汇总概览:基本信息 + 核心指标汇总值与范围;
- 会话对比:每份一行,列为核心指标;
- 汇总明细:全部指标的汇总值、最低、最高、各次数值与汇总方式说明。
- 文件名
PF_SUMMARY_<时间>_<N>份.xlsx。不导出截图。
三、实现范围
- PerfowlCore:
SessionAggregateReport(构建与公式)、SessionAggregateWorkbookWriter。 - PerfowlApp:历史列表多选、汇总窗口
SessionAggregateView、截图条ReportScreenshotStrip(AppKit 滚动视图,滚轮/拖动/定位)。 - 测试:汇总公式(合并均值、次数率、缺失会话)、同 App 限制、导出三页结构。
四、验收
- E2:单元测试覆盖上述公式与导出。
- E4:Owner 在本机选 2–3 份同 App 会话生成汇总报告并导出;截图条滚轮/拖动/点击定位/游标联动可用。
Implementation Update · 2026-11-02
| 文件 | 修改 |
|---|---|
PerfowlApp/ReportScreenshotStrip.swift(新) | 截图条改为 AppKit 滚动视图:鼠标上下滚轮转为左右滚动(触控板横滑不变),NSPanGestureRecognizer 支持按住拖动且不吞单击;单击截图定位游标,双击放大;游标附近(±2 秒)截图高亮并自动滚入可见区。 |
PerfowlApp/SessionReportView.swift | 原横向 ScrollView 替换为新截图条;提示改为“滚轮或拖动浏览 · 单击定位 · 双击放大”。 |
PerfowlCore/SessionAggregateReport.swift(新) | 2–20 份、同一 Bundle ID 的已封存报告汇总;按本文公式生成每个指标的汇总值、各次数值、最低/最高、有数据份数;核心指标与优劣方向;formulaVersionsDiffer 检测所选会话 FPS/Stutter 口径版本不一致。 |
PerfowlCore/SessionAggregateWorkbookWriter.swift(新) | 导出三页:汇总概览、会话对比(含汇总行)、汇总明细(含汇总方式与各份数值);与单份报告同一样式。 |
PerfowlApp/SessionAggregateView.swift(新)、SessionResultCoordinator.swift | 汇总窗口:顶部应用/份数/设备系统/总时长与导出;左侧分类;概览为核心指标卡片(汇总值、范围、k/N 份)与会话对比表(最好绿、最差红,点击打开该份报告);分类页列出各指标汇总与各份数值;设备系统或口径版本不一致时提示。 |
PerfowlApp/SessionReviewViews.swift | 历史测试“多选”:勾选框、只允许同一应用且已结束的测试(其他行置灰并提示原因)、底部“已选 N 份 · 生成汇总报告”。 |
相对设计的偏差
- 每秒 FPS 类的权重使用各份帧统计窗口时长(与“每秒秒数”近似相等),未单独封存每秒秒数。
- 汇总只读取各份已封存的报告值,不重新计算原始数据;旧版本口径的测试仍可汇总,但会显示“口径版本不一致”提示(真实数据中 239 的旧口径 Jank 为 430.91 次/10 分钟,明显高于新口径)。
验证(E2)
- 新增
testSessionSummaryPoolsSealedValuesAndExportsThreeSheets:少于 2 份拒绝;合并均值、流量合计、加权与中位函数;导出三页结构与汇总行。 - 真实数据(本机 3 份同 App 会话,约 4 分钟):汇总窗口渲染与 Excel 三页导出核对正确。
- 截图条交互(滚轮、拖动、联动)需 Owner 在新包上实际操作确认(E4 待测)。
- 回归:Swift 全量 445 项 0 失败(11 项跳过,含两项真实数据手动开启测试;排除既有挂起的
UserReportIntegrationTests)。本批未改 Python。
Validation Update · 2026-11-02:内部包 243 构建与同址安装(E3)
- 来源:main
f0ea741e(含本批汇总报告与截图条,以及同日帧耗时每秒最大值与曲线连线),Developer ID 签名构建 259.1 秒,来源门禁passed。242 因构建期间源码被修改而中止,未产出、未安装。 - 校验:冻结核心 107 个模块与 CLI 和源码一致,严格签名、DMG 与安装后文件树一致,安装后
probeready;启动器只剩/Applications/Perfowl.app。 - 产物:
MacApp/dist/Perfowl-243-macos-x86_64-internal.dmg,148,234,489 B,SHA-256c2d55971198bb005d38ef66e16b2372aac25de721ac4553a5990e62654a33b19;241 安装包与回滚包在私有归档,回滚已核对。 - 未完成:公证暂缓(Gatekeeper exit 3);截图条交互、帧耗时曲线与汇总报告的真机 E4 待 Owner 确认。