Skip to content

自有测试 App:全指标覆盖与长期测试工具设计 ​

供 Owner 审核,未批准实施。 这是设计与口径盘点,不是 App 功能或指标验收通过。2026-10-15 Owner 决定:完整覆盖设计、按当前指标逐步实现;数值允许合理误差、重点排除明显偏离;本轮范围包含启动;工具还需包含网络、卡顿、崩溃、WebView 等真实业务测试。当前不改产品/Fixture、不构建覆盖手机、不采新会话、不发布网站。

1. 审核摘要与范围 ​

  • 真实 Registry 66项 = 54项非启动 + 12项启动。按当前 PerformanceModels.swift 逐项提取,与 site/data/metric-contracts.json 逐字段核同,不沿用旧规则中64的文字快照。
  • 本稿附66行一对一覆盖矩阵,保留既定非启动54项的相对顺序;启动新增独立区块,不把旧台账自动改成“7/66已验收”。旧7/54是历史登记,旧原件已删除不等于本轮复核通过。
  • 54/66是指标数量;网络异常、崩溃、WebView、组合业务是场景能力,不伪造新metricID或掩盖尚未覆盖项。
  • 不承诺每项都可“设定精确系统读数”。每项明确:负载控制、独立/半独立参照、产品来源、系统限制。设计覆盖≠功能实现≠数值校准≠正式验收。
  • 审核配套位于仓库 internal/design/fixture-lab-v1/:离线 review.html(可切换场景、查看66项并导出审核意见)、metric-coverage.json(机器可读矩阵)。原型不连接设备,所有参数仅设计示意,没有假实测结果。机器路径是仓库内文件,不作为站点链接。

2. 现有 App 盘点:复用而不是另造一套 ​

当前 PerformanceProbeFixtureApp.swift 已有CPU 1/2线程与短峰、内存+10/+50MiB/释放及阶梯、主线程停顿、简单请求、受控Crash入口;还有多种默认关闭的参考模块。静态可见不代表当前手机每项已通过。主要短板是入口碎片化、参数与参考模式耦合、统一运行协议不足、网络/WebView/存储/图形场景覆盖不完整。本设计在原工程/同一安装身份下逐步模块化,不新增平行手机App或Mac客户端,不一次性删除/重写旧参考模块。

3. 产品结构与页面 ​

暂称 Perfowl Test Lab(展示名待确认;原安装身份保持)。五个一级入口:

  1. 测试台:当前场景、参数摘要、环境/配额、明确开始/停止、当前阶段、实际工作量、记录质量、最近终态;一键回到轻量空闲。
  2. 场景库:内存、CPU/调度、网络、帧率/卡顿、存储、GPU、启动、设备/能耗、WebView、崩溃/恢复、组合业务;搜索/收藏/预置配方。
  3. 覆盖矩阵:66项逐行列出定义/单位/scope、对应场景、可控制量、参考方式、限制、实现状态、验收状态与证据。独立显示不支持/待核/未测,不用一个“已覆盖”绿点糊成通过。
  4. 运行记录:参数与实际完成量、阶段时间线、异常、停止理由、文件与摘要、与Perfowl/PerfDog对照的关联状态;单轮/配方导出。
  5. 设置与配方:资源上限、受控服务地址、参考采样模式、隐私导出、清理预览、能力列表。隐藏旧调试开关,专家设置显式开启且每轮落有效配置。

场景详情统一:目的 → 预置档 → 参数 → 实际工作 → 可核对指标 → 限制 → 运行记录。单位一律明确;业务字节、源生系统值与候选派生值不同颜色/标签区分,不在UI伪装同一真值。

4. 统一执行与可重复性 ​

状态机:idle → prepared → armed → baseline → stimulus → hold → recovery → sealing → completed;用户取消、资源超限、错误均进入 stopping → cancelled/partial/failed,不得改记completed。Crash是显式终止支路,正常seal缺失是预期事实,不自动伪造成功。

  • 配方固定schema/version、随机种子、参数、阶段顺序、总量上限、时限、参考模式、环境标签与有效配置摘要;开跑后不可静默改值。手动探索与正式配方运行分开。
  • 每轮保存计划值/实际值/单位/工作次数/成功失败/开始结束;所有段(准备、过渡、尾部、失败)保留,正式分母只按批准合同计算,不删异常段美化。
  • iPhone内用明确单调时钟,保留原ticks/timebase;墙钟仅用于查找,主机/手机/JS时钟分域,配对需保留桥接误差,不用ISO字符串直接做毫秒级跨机相减。
  • 本地Run标识不在公开页暴露真实设备/进程/会话身份。Owner审核使用别名,原始身份只私有留存;导出前预览并脱敏URL/token、账号、cookie等。
  • 尽量只运行当前场景所需参考。默认轻量事件记录/1Hz参考,UI ≤2Hz更新;逐帧/高密度采样显式诊断模式,不常驻全指标监控。此为设计目标,待真实测开销,不把1Hz等参数当已验证成果。
  • 停止必须取消任务、关闭文件/连接、释放自有内存/图形资源;启动默认idle,不自动续跑旧负载。残留配置、运行态与崩溃恢复独立显示。

5. 场景库与可控量 ​

MEM · 内存实验室 ​

  • 优先级:首批实现。
  • 可控制:分配20/40/80 MiB;步长、触页/仅保留地址、保持/释放、可回收对象模式;有界上限。
  • 配方示例:空闲20s → 触页20MiB保持20s → 40MiB保持20s → 80MiB保持20s → 释放观察40s(示例不是替换原正式轮时长/分母)。
  • 对照记录:分配/触页/释放事件账本;受支持的本进程内存API与整机VM参考分开记录。
  • 额外工具能力:内存阶梯、循环分配释放、对象缓存、后台前台恢复;不自动制造OOM。
  • 边界:申请量不是footprint,也不是Free变化真值;虚拟预留不等于常驻;失败、压缩和系统回收均保留。

CPU · CPU与调度 ​

  • 优先级:按指标顺序完善。
  • 可控制:1/2/可用核数工作线程;10/30/60/90%忙闲配比;1s周期与突发;线程创建/退出。
  • 配方示例:空闲 → 单线程阶梯 → 多线程 → 短突发 → 恢复(示例不是替换原正式轮时长/分母)。
  • 对照记录:实际累计CPU时间/elapsed;线程生命周期;切换/唤醒参考仅API可读时。
  • 额外工具能力:锁竞争、串并行任务、任务取消、周期唤醒;不使用无限死锁。
  • 边界:忙闲配比不是系统CPU百分比;不强绑大小核;定时次数不等于中断唤醒次数。

NET · 网络实验室 ​

  • 优先级:按指标顺序完善。
  • 可控制:上下行/双向;1/10/50MiB;速率上限;1/2/4并发;HTTP缓存/压缩/重定向;连接复用。
  • 配方示例:空闲 → 固定上传 → 空闲 → 固定下载 → 双向 → 排空(示例不是替换原正式轮时长/分母)。
  • 对照记录:App业务字节+服务端收发/摘要+URLSession任务指标;各层独立。
  • 额外工具能力:慢首包、慢响应、4xx/5xx、超时、截断、取消重试、Range、WebSocket心跳。
  • 边界:业务/TLS/网络层不混算;速率是限速请求不是精确吞吐;模拟响应延迟不是物理丢包。

FRAME · 帧率与卡顿 ​

  • 优先级:按指标顺序实现。
  • 可控制:请求15/30/60及硬件支持的刷新范围;主线程40/100/200/500ms有界阻塞;频率/次数。
  • 配方示例:平滑滚动 → 单次阻塞 → 周期阻塞 → 后台计算对照 → 恢复(示例不是替换原正式轮时长/分母)。
  • 对照记录:实际阻塞开始结束与工作完成;DisplayLink仅回调参考;外部呈现序列独立复算。
  • 额外工具能力:长列表、图片解码、布局抖动、动画、Canvas/Metal;不以截图轮询作帧真值。
  • 边界:请求帧率不是实际呈现FPS;注入1次阻塞不等于某算法恰报1次Jank。

IO · 存储与文件 ​

  • 优先级:按指标顺序实现。
  • 可控制:顺序/随机;读取/写入;1/64/1024KiB块;总量;覆盖/新文件;缓存与同步标志。
  • 配方示例:空闲 → 有界写入 → 明确缓存条件读取 → 同步收尾 → 清理自有工作文件(示例不是替换原正式轮时长/分母)。
  • 对照记录:成功read/write字节、偏移、调用结果与时刻;系统I/O计数另列。
  • 额外工具能力:小文件、JSON/图片缓存、SQLite事务、磁盘不足的预置错误路径。
  • 边界:逻辑写入不等于物理磁盘写入;fsync不承诺消除全部系统缓存;不访问其他App。

GPU · GPU与图形 ​

  • 优先级:按指标顺序实现。
  • 可控制:简单/复杂几何、纹理、分辨率倍率、过绘、shader负载;固定时长。
  • 配方示例:静态 → 几何负载 → 像素负载 → 混合 → 恢复(示例不是替换原正式轮时长/分母)。
  • 对照记录:实际提交/完成GPU工作;同口径外部GPU计数与PerfDog可用项。
  • 额外工具能力:图形压力、帧率与耗能联动;资源复用避免测试台自身制造假泄漏。
  • 边界:工作量不是Renderer/Tiler百分比;原生计数器是动态多维schema,不虚构所有硬件支持。

START · 启动与生命周期 ​

  • 优先级:首批内存之后的独立阶段(待审核)。
  • 可控制:基线;will/didFinish、scene连接与首屏工作0/100/300ms有界延迟;暖恢复;首屏本地/网络内容分开。
  • 配方示例:主机提前准备采集 → 受控进程冷启动 → 首屏标记 → 可交互标记 → 显式结束(示例不是替换原正式轮时长/分母)。
  • 对照记录:启动请求与观测在主机;App可进入回调边界;CoreProfile真实首尾;相同端点时才比较绝对值。
  • 额外工具能力:回前台、页面首开、延迟初始化、首屏失败/超时、启动崩溃;不每次启动自动重放上轮负载。
  • 边界:App内时钟覆盖不到System BEGIN;onAppear/DisplayLink/首个CA提交不是首帧物理呈现;不把九阶段相加成Total。

ENERGY · 能耗与设备状态 ​

  • 优先级:按指标顺序实现。
  • 可控制:CPU/GPU/网络/屏幕/前台定位单变量工作;充电与连接状态记录;定位显式授权。
  • 配方示例:空闲 → 单负载 → 恢复;不同来源和供电条件分开批次(示例不是替换原正式轮时长/分母)。
  • 对照记录:工作账本与设备状态;源生能耗评分、放电电流、电压、温度分域。
  • 额外工具能力:持续负载下的变化、拒绝权限分支、低电量/热状态下的适配。
  • 边界:能耗cost不是mW;无仪器时不声称物理校准;不绕过系统定位权限或为升温无限加压。

WEB · WebView实验室 ​

  • 优先级:通用工具场景。
  • 可控制:内置离线页面/受控本地服务;DOM规模、JS短长任务、图片、Canvas、缓存、路由、刷新。
  • 配方示例:原生基线 → WKWebView首开 → 列表滚动 → JS负载 → 关闭释放 → 再打开(示例不是替换原正式轮时长/分母)。
  • 对照记录:navigation回调、页面performance标记、JS事件、资源请求与native生命周期。
  • 额外工具能力:白屏/加载失败、桥接消息、导航取消、Web内容进程终止回调、前后台恢复。
  • 边界:Web内容/网络在独立进程,主进程指标不自动代表整个网页;JS时间与native时钟需显式桥接。

CRASH · 崩溃与恢复 ​

  • 优先级:通用工具场景。
  • 可控制:仅自有进程:显式abort、受控断言失败、抛错但被捕获;按次预先武装。
  • 配方示例:记录并落盘意图 → 倒计时/确认 → 触发一次 → 下次启动显示上轮未完成并导出(示例不是替换原正式轮时长/分母)。
  • 对照记录:持久化意图/最后事件/下次启动恢复;系统崩溃报告若可得单独关联。
  • 额外工具能力:采集中目标退出、异常断流、重开后新进程归属、部分文件可读性。
  • 边界:意图不是崩溃成功证据;未正常结束不能自动断言crash;不默认OOM或watchdog,不永久挂死UI。

MIX · 真实业务组合 ​

  • 优先级:单指标通过后的扩展。
  • 可控制:列表/图片流、上传下载、页面跳转、WebView、后台前台、资源释放的有序组合。
  • 配方示例:可重复短业务配方 → 固定检查点 → 取消/恢复 → 明确终态(示例不是替换原正式轮时长/分母)。
  • 对照记录:各子场景事件与实际完成量;逐进程/设备/呈现域分层。
  • 额外工具能力:弱服务、长列表、图片缓存、会话恢复、重复进入退出。
  • 边界:组合压力用于集成回归,不替代单变量定位或每指标验收。

6. 四类重点扩展的具体要求 ​

6.1 网络:长期常用,不止一个请求按钮 ​

支持HTTP/HTTPS固定载荷上下行、双向、并发、限速、连接复用/新建、上传下载进度;保留取消/重试/部分成功。受控服务端提供固定长度/内容摘要、echo、指定状态码、重定向、延迟首字节、缓慢分块、提前断开、Range与WebSocket echo/心跳。记录请求层、业务层、服务端成功接收层与系统层,不把URLSession字节直接叫网卡线速字节。

网络服务复用现有Mac环境,显式按需启动、停止后退出,限制地址/连接/流量/时限,不建常驻服务。手机到本机需要可达的受控网络地址,不能填手机自己的localhost。只用自有端点,不拿银行或用户账号服务做故障注入。ATS例外仅限必要本地测试域,不全局关闭TLS验证。HTTP故障模拟不是网络层丢包/弱信号;真正飞行模式/Wi-Fi切换单列需要配合的外部条件,不擅自改用户连接。

6.2 卡顿:让“卡在哪里、卡了多久”可解释 ​

提供主线程有限忙任务、主线程有限等待、后台同量任务对照;设置40/100/200/500ms与周期/次数,总阻塞预算有界。长列表/图片解码/布局、图形过绘作为真实场景。实际测每次工作起止,不把计划时长当实际;UI在阻塞时不能实时响应,严格限制单次时长并预先显示。5秒级Hang独立危险档,不默认加入普通回归;无限死锁不提供常规入口。

6.3 崩溃:一次性触发、可靠恢复、不污染指标轮 ​

显式断言/abort只终止此自有App;错误捕获与真正进程终止是不同场景。运行前显示风险、确认、写出并关闭触发意图,再触发一次;冷启动后不自动二次崩溃。OS报告可用性由实际环境决定,不在信号处理器里承诺安全写完整JSON,不把“文件没封口”一律认定为Crash。OOM/jetsam/watchdog只有独立高风险合同和真实系统证据才测试/定类,默认不执行。崩溃轮用于Perfowl退出/断流/部分保存检查,不混进正常连续性五轮以缩分母。

6.4 WebView:页面体验与跨进程边界一起测 ​

内置离线页面保证可复现;受控联网页面验证资源加载/缓存/错误。覆盖首开、重载、前进后退、DOM列表、JS短/长任务、图片解码、Canvas、native↔JS消息往返、视图销毁与重新创建。导航完成、DOMContentLoaded、load、页面自定义可交互标记分开,不统一叫“首帧”。Web内容进程终止回调只用于检测,不能保证用公开API可精确主动终止该进程。独立Web/网络进程的工作不默认合并到宿主App进程;process-group如果未来产品支持,另立归属协议,不偷偷改当前66项scope。

7. 启动:12项全部设计,不只一个Total ​

启动单独准备采集再受控进程冷启动;前台返回和页面首次打开另列,不叫冷启动。App本身不能控制System Interface/系统UIKit初始化的精确时长;这几项用真实系统span与基线比较,不伪造“设定值”。

  • 正常基线:最小启动工作,无网络依赖,轻量首屏与可交互标记分开。
  • 控制变体:选定真实回调/首屏路径增加0/100/300ms工作,记录真实入口出口;实际耗时可能超过设定。下一轮参数须在launch前准备,不能开App读设置后把本次当冷启动。
  • 单独看“有无可信端点/目标绑定”“重复获取”“对额外工作的响应”“数值独立对照”;不能只凭每轮有值判准确。
  • App Launch Total沿用现有系统BEGIN→真实Initial Frame END公式,不改成App内部时间,不用onAppear/DisplayLink/下一帧补端点,不把九阶段相加。
  • 未触发的条件回调保留这一指标行,只有可证明路径未发生时记not-applicable;没有证据则missing。全66项覆盖不是强迫每一启动出现全部回调。
  • 启动参考“无App内详细记录”与“启用回调记录”各一个模式,评估观察开销;重型文件/网络/参考模块不在首帧前自动创建。
  • 首轮开发保持现有应用生命周期;若当前SwiftUI路径不能提供某些真实delegate边界,先提独立设计变更与来源差异,不为凑九阶段改变生命周期后冒充原App。

8. 允许误差:可执行的新原则(量化细则待本稿审核) ​

Owner已同意“不明显偏离,允许误差”。本稿将其操作化,不再用每点与设定值完全相等或追求所有指标物理校准作为普通交付先决条件。源可信、目标scope正确、无虚构/陈旧、连续性、显式缺失与固定轮数仍是硬要求。

8.1 比较步骤 ​

先查scope、单位、时钟与窗口,再比稳态数值/负载增量/异常峰值/恢复;不支持同口径对照时明确“对照未建立”,不算通过。PerfDog是交叉参照而非绝对真值;同源两工具相近不自动提供独立校准。先短测共存是否互相干扰,冲突则按固定配方A/B/B/A交替;交替只证场景统计,不证逐点同步,变化快的Free不能据此得出同一瞬时相等。

8.2 提议的异常筛查阈值模板 ​

以下是本项目待审核的工程建议,不是行业标准,不写回既有合同。以同口径、对齐窗口参考R为基准,误差包络 T=max(A,B*abs(R));只有参考稳定/可比时才适用。稳态连续3个已完成1s窗口超T则“明显偏离”,整轮可比窗口超过5%落外也不接受。瞬态峰值/极端值另查,不能用均值掩盖;负值哨兵、错归属、陈旧值即时失败,不享误差豁免。窗口不足或不可比记录unknown,不能填0或删分母。

指标类别初拟A / B附加要求
CPU同口径占用3个百分点 / 15%未归一化可>100%,核数对齐;不把3%写成3个百分点
进程内存16MiB / 10%参考为同类系统API,不是申请量;resident/footprint/virtual分别审
整机Free/Available64MiB / 15%各自定义与可信来源成立;环境波动与采样时差单列,不能因此豁免来源漂移
网络采集累计量256KiB / 10%只比相同层/方向/scope/时间窗;未知协议层开销先解决,不能机械比业务payload
FPS3fps / 10%参考为可比呈现统计,不是请求FPS
帧耗时P50/P955ms / 15%同一窗口/算法;同一原序列离线复算按原取整规则而不是放宽此误差
启动50ms / 20%仅端点语义相同的参照;不同首帧定义只作旁证;受控增量响应单独检查
线程/枚举/派生公式不套通用百分比创建增量/已知状态/算法结果核对;原派生公式与取整不因允许误差而改变
GPU/调度/能耗与电池按源能力逐项预置无同口径参考只做来源/趋势/合理性;无仪器不作物理校准,缺口保留

有规范性来源范围的字段必须额外满足其范围;所有异常筛查保留原参考质量。应用0负载也有基线开销;合法0不自动异常。调大负载并重复单变量检查能帮助定位,但不能重复抽样直到过关。

8.3 连续性、轮数与旧合同关系 ​

本次Owner改变数值误差方向,不等于取消连续性。建议沿用当前有效v5每项固定五轮及其原名义分母/连续性与有效性政策;时序/计数/向量/一次性启动分别用适用合同,不能把启动12项强塞成240点连续指标。启动新增五次完整独立启动的正式合同须在执行前落盘,诊断/负载增量轮不替换失败正式轮。

当前metric-stage-targets-v3.json/nonstartup-v5.json与现有门禁均未改。本稿审核后,先追加新版本并明确supersedes哪一条数值判断,历史数字/误差/分母/失败记录保留;不同版本结论不混为旧门通过。在Owner认可本稿之前不执行新阈值。

9. 66项一对一覆盖矩阵 ​

编号N01–N54沿用既定非启动顺序;S01–S12是新增启动设计范围,不改变原54顺序。每一行的metricID/scope/unit/source/version详见同源JSON,下面逐项提供场景/对照/边界。所有行当前均为设计待审核,不是新验收通过。更多维度(逐核、GPU动态计数器)须在对应行展开实际维度清单,不能一个示例代表全部维度。

编号指标 / metricIDscope · unit场景控制与对照边界
N01目标App CPU
ios.process.cpu.non_normalized
process · percentCPU线程忙闲阶梯与累计进程CPU时间/实际时间窗设置忙占比不是结果百分比;明确非归一化口径
N02物理内存占用
ios.process.memory.physical_footprint
process · bytesMEM触页阶梯与本进程footprint/resident分别观察footprint/resident不互换;释放不保证系统读数即时回到基线
N03驻留内存
ios.process.memory.real
process · bytesMEM触页阶梯与本进程footprint/resident分别观察footprint/resident不互换;释放不保证系统读数即时回到基线
N04虚拟内存
ios.process.memory.virtual
process · bytesMEM虚拟预留/触页切换;本进程虚拟地址空间读数虚拟大小不等于申请业务量或常驻量
N05线程数
ios.process.thread.count
process · countCPU创建/退出N个常驻线程与本进程线程枚举线程池与框架基线存在;GCD任务数不是线程数
N06目标App网络发送
ios.process.network.send_rate
process · bytes-per-secondNET固定不压缩载荷;服务端账本/任务指标/累计来源整机/进程、上下行、业务/协议层分别匹配;Web进程另列
N07目标App网络接收
ios.process.network.receive_rate
process · bytes-per-secondNET固定不压缩载荷;服务端账本/任务指标/累计来源整机/进程、上下行、业务/协议层分别匹配;Web进程另列
N08整机空闲内存
ios.device.memory.free
device · bytesMEMhost VM free与原始页大小(API可读时);触页负载只比较Free;不拿Available顶替;分配量不等于整机减少量
N09整机可用内存候选
ios.device.memory.available
device · bytesMEMfree/external/purgeable原字段及候选算法;跨工具先核定义不把可分配上限/Free当Available,仍披露candidate
N10整机CPU总量
ios.device.cpu.total
device · percentCPU整机CPU状态差分;核数与归一化公式分别检查自有App只贡献部分整机负载;原始与除核数结果分开
N11整机CPU归一化
ios.device.cpu.total.normalized
device · percentCPU整机CPU状态差分;核数与归一化公式分别检查自有App只贡献部分整机负载;原始与除核数结果分开
N12逐核CPU
ios.device.cpu.core_usage
device · percentCPU逐核系统CPU状态差分与线程阶梯调度器决定落核;缺核不补0,不能指定某核精确占用
N13上下文切换率
ios.process.scheduler.context_switch_rate
process · count-per-secondCPU有界锁竞争/周期等待;系统累计计数若可读创建等待任务数不等于上下文切换或硬件中断次数
N14中断唤醒率
ios.process.scheduler.interrupt_wakeup_rate
process · count-per-secondCPU有界锁竞争/周期等待;系统累计计数若可读创建等待任务数不等于上下文切换或硬件中断次数
N15磁盘读取速率
ios.process.disk.read_rate
process · bytes-per-secondIO成功读写字节账本及系统进程I/O累计值逻辑调用/页缓存/物理IO分层,不能强求业务字节相等
N16磁盘写入速率
ios.process.disk.write_rate
process · bytes-per-secondIO成功读写字节账本及系统进程I/O累计值逻辑调用/页缓存/物理IO分层,不能强求业务字节相等
N17整机网络发送
ios.device.network.send_rate
device · bytes-per-secondNET固定不压缩载荷;服务端账本/任务指标/累计来源整机/进程、上下行、业务/协议层分别匹配;Web进程另列
N18整机网络接收
ios.device.network.receive_rate
device · bytes-per-secondNET固定不压缩载荷;服务端账本/任务指标/累计来源整机/进程、上下行、业务/协议层分别匹配;Web进程另列
N19屏幕刷新率
ios.display.refresh_rate
foreground-device · hertzFRAME设备能力/设置与外部实际refresh_intervalDisplayLink请求频率不是实际屏幕刷新率
N20前台FPS
ios.foreground.fps
foreground-device · frames-per-secondFRAME平滑/阻塞工作与外部实际呈现序列不能用请求FPS或回调次数作物理呈现真值
N21单帧耗时
ios.frame.time
foreground-device · millisecondsFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N22帧耗时P95
ios.frame.time.p95
foreground-device · millisecondsFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N23帧节奏抖动
ios.frame.pacing_jitter
foreground-device · millisecondsFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N24平均FPS
ios.frame.fps.average
foreground-device · frames-per-secondFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N25FPS至少18占比
ios.frame.fps.at_least_18_percent
foreground-device · percentFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N26FPS至少25占比
ios.frame.fps.at_least_25_percent
foreground-device · percentFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N27帧耗时至少100ms占比
ios.frame.ftime_ge_100_percent
foreground-device · percentFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N28帧耗时正向突增率
ios.frame.ftime_positive_delta_gt_100_per_hour
foreground-device · count-per-hourFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N29FPS下降率
ios.frame.drop_per_hour
foreground-device · count-per-hourFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N30FPS中位范围占比
ios.frame.med_range_percent
foreground-device · percentFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N311%低帧率
ios.frame.one_percent_low_fps
foreground-device · frames-per-secondFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N32小卡顿率
ios.frame.small_jank_per_10min
foreground-device · count-per-10-minutesFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N33卡顿率
ios.frame.jank_per_10min
foreground-device · count-per-10-minutesFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N34大卡顿率
ios.frame.big_jank_per_10min
foreground-device · count-per-10-minutesFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N35卡顿时间占比
ios.frame.stutter_percent
foreground-device · percentFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N36微卡顿率
ios.frame.tiny_jank_per_10min
foreground-device · count-per-10-minutesFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N37流畅度
ios.frame.smooth
foreground-device · scoreFRAME真实呈现序列离线按该metric公式重算;记录实际阻塞同源重算只证算法;跨源同定义才证一致性;低样本不补值
N38GPU渲染利用率
ios.foreground.gpu.renderer_utilization
foreground-device · percentGPU几何/像素工作量阶梯与可用外部GPU源不是预置GPU百分比;动态计数器逐维列单位,unsupported不冒充0
N39GPU平铺利用率
ios.foreground.gpu.tiler_utilization
foreground-device · percentGPU几何/像素工作量阶梯与可用外部GPU源不是预置GPU百分比;动态计数器逐维列单位,unsupported不冒充0
N40GPU整体利用率
ios.foreground.gpu.device_utilization
foreground-device · percentGPU几何/像素工作量阶梯与可用外部GPU源不是预置GPU百分比;动态计数器逐维列单位,unsupported不冒充0
N41GPU原生计数器
ios.device.gpu.counter.source_native
device · source-native-countGPU几何/像素工作量阶梯与可用外部GPU源不是预置GPU百分比;动态计数器逐维列单位,unsupported不冒充0
N42总能耗评分
ios.process.energy.total_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N43CPU能耗评分
ios.process.energy.cpu_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N44GPU能耗评分
ios.process.energy.gpu_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N45网络能耗评分
ios.process.energy.network_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N46定位能耗评分
ios.process.energy.location_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N47显示能耗评分
ios.process.energy.display_cost
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N48能耗服务开销评分
ios.process.energy.overhead
process · source-native-costENERGY对应CPU/GPU/网络/定位/屏幕工作与源生costcost不是电功率;定位需真实授权;overhead不设置目标值
N49整机热状态
ios.device.thermal.status
device · enum-rawENERGY受控负载+ProcessInfo热状态与源枚举分别观察不同服务热状态不假定一一映射;严重状态立即停止加压
N50电池电压
ios.device.battery.voltage
device · millivoltENERGY供电/充电记录;同一快照原字段及换算;仪器可选无仪器不作独立校准;USB充电不当放电;原始温度非摄氏度
N51电池放电电流
ios.device.battery.current
device · milliampereENERGY供电/充电记录;同一快照原字段及换算;仪器可选无仪器不作独立校准;USB充电不当放电;原始温度非摄氏度
N52电池放电功率
ios.device.battery.power
device · milliwattENERGY供电/充电记录;同一快照原字段及换算;仪器可选无仪器不作独立校准;USB充电不当放电;原始温度非摄氏度
N53电池原始温度
ios.device.battery.temperature_raw
device · source-nativeENERGY供电/充电记录;同一快照原字段及换算;仪器可选无仪器不作独立校准;USB充电不当放电;原始温度非摄氏度
N54电池摄氏温度
ios.device.battery.temperature_celsius
device · degree-celsiusENERGY供电/充电记录;同一快照原字段及换算;仪器可选无仪器不作独立校准;USB充电不当放电;原始温度非摄氏度
S01观测到进程运行耗时
ios.process.startup.observed_running_ms
process · millisecondsSTART主机请求/进程观测;保留轮询误差界不是首帧;App内标记不替代主机观测
S02观测到前台就绪耗时
ios.process.startup.foreground_ready_ms
process · millisecondsSTART主机请求/前台观测与App活跃回调并列活跃回调不是外部前台检测的同一时刻
S03启动总耗时
ios.process.startup.app_launch_total_ms
process · millisecondsSTART基线及回调/首屏额外工作;CoreProfile原始端点独立复算起点必须真实系统BEGIN;缺失不补0;不同首帧定义不直接对等
S04系统接口初始化
ios.process.startup.system_interface_ms
process · millisecondsSTART同包基线与真实生命周期span;不伪造系统阶段App不直接控制该系统阶段耗时;OS/冷暖缓存记录,缺失保留
S05静态运行时初始化
ios.process.startup.static_runtime_ms
process · millisecondsSTART同包基线与真实生命周期span;不伪造系统阶段App不直接控制该系统阶段耗时;OS/冷暖缓存记录,缺失保留
S06UIKit初始化
ios.process.startup.uikit_initialization_ms
process · millisecondsSTART同包基线与真实生命周期span;不伪造系统阶段App不直接控制该系统阶段耗时;OS/冷暖缓存记录,缺失保留
S07UIKit场景创建
ios.process.startup.uikit_scene_creation_ms
process · millisecondsSTART同包基线与真实生命周期span;不伪造系统阶段App不直接控制该系统阶段耗时;OS/冷暖缓存记录,缺失保留
S08willFinishLaunching回调
ios.process.startup.will_finish_launching_ms
process · millisecondsSTART相应真实回调入口/出口及0/100/300ms额外工作回调未发生须有证据才记不适用;不人为制造系统span
S09didFinishLaunching回调
ios.process.startup.did_finish_launching_ms
process · millisecondsSTART相应真实回调入口/出口及0/100/300ms额外工作回调未发生须有证据才记不适用;不人为制造系统span
S10sceneWillConnect回调
ios.process.startup.scene_will_connect_ms
process · millisecondsSTART相应真实回调入口/出口及0/100/300ms额外工作回调未发生须有证据才记不适用;不人为制造系统span
S11sceneWillEnterForeground回调
ios.process.startup.scene_will_enter_foreground_ms
process · millisecondsSTART相应真实回调入口/出口及0/100/300ms额外工作回调未发生须有证据才记不适用;不人为制造系统span
S12首帧渲染阶段
ios.process.startup.initial_frame_rendering_ms
process · millisecondsSTART首屏复杂度/绘制工作阶梯与外部真实span提交绘制/可交互/首次呈现三者分列

10. 记录与导出协议 ​

每轮目录只新增,结构拟为:plan.json / effective-config.json / events.jsonl / 启用的reference文件 / summary.json / manifest.json。真实私有标识只在私有目录;公开脱敏导出必须另存,不回改原件。summary保存requested/actual/cancelled/failed、参考能力/权限、环境与理由;partial不能补写completed。

  • 事件包含schema、时钟域、单调时间、阶段、负载类型、计划与实际量、单位、结果/错误;原值精度不为界面取整而丢失。
  • 完整封口只在flush/关闭成功并记录文件长度/SHA后成立;失败文件保留可读前缀。Crash意图提前落盘,不承诺Crash后还能封口。
  • 网络文件只存受控载荷种子/长度/摘要,不默认保存全部大payload;导出主机用有界流式搬运。截图默认OFF,不用来伪装帧真值。
  • 自有App/Perfowl/PerfDog分别存原件与版本;对照报告引用三方SHA与运行关联,不改原导出。导入格式按实际安装版本适配,不假设当前Info里的1.0就是产品发布版本。
  • 自动配方在手机自己计时执行;Mac协调器只负责准备/显式启动/状态等待/导出;不默认依赖WDA/XCTest或截图点击轮询。长期工具可手动操作、保存配方、离线运行,不依赖本次AI上下文。

11. 架构决策 ADR-TESTLAB-01(Proposed) ​

决策者:Owner。 选择原工程模块化:ScenarioDefinition → RunCoordinator → WorkloadEngine → EventRecorder/ReferenceAdapter → RunStore/Export;SwiftUI只显示状态与发意图,资源持有在受控worker中。一个Run只启动所需模块,普通/验收/危险诊断三种运行模式显式区分。

方案成本/优点风险结论
继续在原大View中加按钮和隐式编译开关首次写得快参数/参考/生命周期耦合,容易重演配置不生效不选
原工程同身份,逐场景抽模块、统一运行协议复用旧代码与安装,按项交付,容易隔离参考开销需保持旧参考兼容与来源记录推荐
另建新App/独立SDK/新常驻服务表面干净多版本安装、证据分裂、额外环境与维护不选

工作负载与参考采样解耦,所有参考默认OFF;不得把验证代码注入商店App或Perfowl目标进程。参考API不可读时显示unavailable,并保留错误,不用另一含义的API偷偷顶替。

12. 资源与停止策略(设计预算,尚未实测) ​

  • 复用现有Swift/Xcode/Python环境、单个手机安装;不新建常驻环境。模块按需加载,复杂度O(事件数/传输字节),有界队列/批写,数据量大时流式导出,不重复全库扫描。
  • 一次一个基础负载;组合配方显式限定并发。主线程不做日志编码/文件哈希/大图片解码;卡顿测试是明确例外且有最长阻塞。
  • 普通场景默认≤180s、上限600s;网络默认≤50MiB、可审核上限512MiB/并发4;内存默认≤80MiB、普通档上限min(256MiB,物理内存10%);所有分配失败立即停,不当OOM成功。需要更大负载另存高风险配方,不静默抬上限。
  • 持续负载出现memory warning、热状态serious/critical、资源配额或写失败时立即停止并记录partial,不为了目标数值继续加压。电池场景记录供电,USB与无线/放电批次分开。普通档禁止故意追求热极限或耗尽磁盘。
  • App参考+记录开销设计目标:空闲额外CPU≤2个百分点,额外常驻≤20MiB,普通日志≤10MiB/轮;这不是当前通过事实,也不修改旧1ms合同。真实设备按同包OFF/ON受控对照实测平均/p95处理延迟、CPU、RSS、队列峰、I/O、首响应与停止收尾,不把合成微基准变成无限阻塞。
  • 开始/批末/长测30分钟检查空间,主机≥10GiB且≥预计新增两倍,手机自有工作目录有上限;只清已明确可重建/已完成且无引用的测试payload缓存。原始失败/待分析/引用证据不自动按年龄删除;清理预览列范围/字节/理由,必要摘要与验收证据先确认留存策略。用户已删除旧归档的事实不反向改写为已保留。

13. 分阶段交付与验收 ​

阶段本阶段产物开发退出条件不代表什么
D0 本稿66项映射、场景库、可点原型、误差建议Owner逐项审核范围与边界不代表任何新App/指标通过
D1 公共骨架+当前内存配方、轻量记录、停止恢复、内存控制;旧参考按需适配当前场景可重复、实际量可导出、开销及安装核对成立不等于Free来源/正式五轮已通过
D2 当前Free指标交付来源/异常排查+新合同正式五轮+签名同址覆盖数值/质量/五轮/证据/提交发布闭环完成不跳过来源漂移或其它指标
D3 启动专阶段(提议插入)12项启动场景与逐项结果基线/边界/控制变体成立,Total与阶段分别裁定缺阶段不伪造0;有Total不是12/12全部通过
D4 原54余项按序推进每项所需的网络/调度/IO/帧/GPU/设备模块当前指标正式闭环后推进下一项不因场景库按钮齐全宣布全指标完成
D5 长期工具整体验收WebView/崩溃/组合业务、兼容矩阵、用户说明与回归配方手机与Mac单版本安装;正常/异常/恢复与数据导出测试不承诺所有iOS/机型和物理校准已完成

Owner要求本轮包含启动,故提议在当前Free关闭后插入启动专阶段,原非启动54相对次序不变;插入位置是本稿审核项,尚未执行。不能因开发通用工具绕过当前指标的顺序门。

每项正式验收后依旧窄提交、双远程同提交(GitLab仅一次)、更新知识库/开发记录/归档并发布网站;当前设计待审核不推送共享WIP、不发布草稿或发送“工具批次完成”通知。测试包后续同址覆盖,不并行安装;公证按Owner此前暂缓测试包的要求与最终正式分发要求分开说明。

14. Owner审核清单 ​

  1. 66项完整映射是否漏掉实际需要的指标或边界?不把设计覆盖看作全部可准确校准。
  2. 一级页面与11类场景是否符合长期工具使用习惯?是否需要优先保留某类业务配方?
  3. 误差包络建议是否接受;未匹配scope/时钟/来源时不能用宽容差充当通过。
  4. 当前内存之后插入启动专阶段是否认可;其它54相对顺序不变。
  5. 崩溃/长Hang等危险场景采用一次确认、可恢复、不默认自动执行;WebView跨进程单独展示。
  6. 本地受控网络服务按需运行、不常驻;普通资源上限、导出/保留/清理方式是否合适。

本轮停在设计审核,不自动进入实现。 审核意见修改本稿形成定稿,再拆首个实施合同。未来实施追加带日期更新,不回改历史实测或旧验收报告。

15. 证据与来源 ​

E1:本地Registry/合同/Fixture静态盘点;覆盖表生成检查不是E2构建或E4真机验收。现有阶段状态见内部handoff与原v5台账,不能从本稿推导新通过数。

Owner审核结果 · 2026-10-15 ​

Owner已审核通过并授权开发与验收。以上审核稿内容保留;正式执行依据转入实施与验收总计划。本次批准不是App或指标已通过。

Perfowl · Performance Observer