Architecture 01 · iOS-first Performance Platform
Perfowl 产品成熟方案 v1:先建立可信 iOS 性能闭环,再逐层对齐 PerfDog
这份方案把 client_perf、Codesign4QC、Apple Instruments、DVT 开源生态和 PerfDog 产品调研合并为一套可长期演进的产品架构,同时明确哪些决策已经成熟、哪些仍需真实设备与样本才能定案。
Decision
决策结论
开发启动条件
Gate 0 的指标对照、采集器对比、兼容矩阵和开销实验全部出具可复现报告。
首版成功标准
可信、稳定、可解释、可回放,而不是先追求七平台、云端和 AI 功能数量。
ADR-001
架构决策记录
| 项目 | 决定 |
|---|---|
| 状态 | Proposed · 等待 Gate 0 证据和用户批准 |
| 产品范围 | 第一阶段只做 macOS Host + iOS 真机,先覆盖通用 App/游戏性能监控主路径 |
| 采集架构 | DVT GeneralCollector 负责持续实时指标;xctrace TraceAdapter 负责按需深度诊断;ExtensionSDK 负责业务语义 |
| 数据原则 | 原始数据 append-only;Normalized Metric 与 Analysis 可重算;所有指标携带来源、单位、方法版本和质量 |
| 交付形态 | 原生 macOS 桌面端为第一入口;本地 Service/CLI 在稳定桌面主链路后开放;云端最后建设 |
| 关键后果 | 架构可容纳采集器替换和跨平台 Adapter,但前期需要投入统一时钟、能力矩阵、Session Schema 和验证实验室 |
Product contract
目标、用户与边界
目标用户
性能测试、客户端开发、游戏研发、质量平台和设备实验室团队;既支持手工探索,也支持自动化回归。
核心任务
连接设备 → 选择 App/进程 → 选择模板 → 采集并标记场景 → 定位异常区间 → 对比基线 → 导出可追踪报告。
首版范围
iOS CPU、内存、FPS 趋势、GPU、网络累计量、线程/唤醒等基础指标;实时曲线、Marker/Scene、Session 回放、报告和质量状态。
后续范围
FrameTime/Jank、启动、日志/Crash/Jetsam、Time Profiler、Hitches、GPU Counter、网络事务、能耗、CLI/CI、多设备和 Extension。
明确后置
Android/PC/主机、云组织/RBAC、MCP、Skills 和 AI 分析。它们依赖稳定的数据本体,不进入第一阶段关键路径。
非目标
不照搬 PerfDog 页面结构,不把厂商算法当绝对真值,不用 Simulator 结果代表真机,不用“有曲线”代替数据可信度。
Reuse map
当前基座能力如何进入 Perfowl
| 输入 | 可复用思想 | 需要重做 | 进入模块 |
|---|---|---|---|
| client_perf | go-ios + py-ios-device 组合、每设备长连接、任务/标签/对比、原始数据归档 | 采样调度、生命周期、数据模型、错误状态、安装可用性与统计 | DeviceRuntime 参考、用户工作流参考 |
| Codesign4QC | provider 隔离、PID 重绑 generation、Schema v2、优先级背压、质量计数、Session、Marker、离线报告 | GPU 单位、多场景规则、指标请求注册、时钟和高频报告内存 | GeneralCollector、EventPipeline、SessionStore 核心参考 |
| Apple Instruments | Template/Instrument、Trace/Run、Track/Detail/Inspector、原始与 Modeler 分离、Profile→Fix→Verify | xctrace 实时化假设、固定 XPath、对第三方 App 源码级诊断预期 | TraceAdapter、分析体验与验证基准 |
| pymobiledevice3 | 现代 DVT、iOS 17+ tunnel、Sysmontap/Graphics/Network/Energy/Core Profile | 持续流、自动化并存、断连、版本和分发回归 | GeneralCollector 默认候选 |
| go-ios | 跨平台二进制、设备与 tunnel 控制、Sysmontap | 复杂 DTX payload、持续 Core Profile 与版本兼容 | DeviceRuntime/Collector 备选候选 |
| py-ios-device | 120Hz、Jank、网络、生命周期、GPU Counter 的实现线索 | 原始事件、算法和真值证据 | FrameLab 研究输入,不直接进入产品 |
| PerfDog 公开接口 | Service、CLI、报告上传、Label/Note、自定义指标和多设备工作流 | 内部实现、算法与精度需独立验证 | 产品能力目标与外部 API 参考 |
High-level architecture
总体架构:单机分层、采集器可替换
建议宿主技术
- 桌面端:Swift + SwiftUI 负责应用壳和业务状态;高密度时间线使用独立 ChartRenderer 协议,先以 Canvas/AppKit 实现并通过十万点交互基准决定是否下沉 Metal。
- 核心领域:纯 Swift Package,包含 Session、Metric Registry、Query、Analysis、Rule、Report;不依赖具体 UI,后续 Desktop/CLI/Service 共用。
- 采集 Sidecar:通过稳定的 Protobuf 契约与 Host 隔离。Gate 0 默认比较 pymobiledevice3 与 go-ios,不在业务代码中暴露任一库的数据结构。
- xctrace:复用用户系统中可用的 Xcode,作为可选 Deep Adapter;不存在或版本不支持时返回明确 capability 状态。
- 外部接口:MVP 后开放本机 gRPC Service 与 CLI;内部 Sidecar IPC 优先使用 Unix Domain Socket + length-delimited Protobuf,默认不监听局域网。
Module boundaries
模块职责与禁止越界
| 模块 | 职责 | 输入 / 输出 | 禁止承担 |
|---|---|---|---|
DeviceRuntime | Hotplug、配对、Developer Mode、DDI、iOS 17+ tunnel、App/进程枚举 | DeviceCapabilitySnapshot、连接状态 | 指标算法和 UI 展示 |
SessionOrchestrator | 创建 Run、选择模板、绑定设备/App/进程、协调所有 Collector | SessionPlan → SessionState/Event | 解析私有协议细节 |
CollectorSupervisor | 进程隔离、心跳、取消、超时、重启预算、stderr 诊断、版本/哈希 | CollectorCommand ↔ CollectorEnvelope | 静默重试和丢弃错误 |
GeneralCollector | Sysmontap/Graphics 等持续指标、进程重绑、raw event | SourceEvent + Capability | Jank/Pass/Fail 结论 |
TraceAdapter | xctrace record/export/symbolicate、Trace 产物与 Schema 快照 | TracePlan → Artifact/Event | 强行提供低延迟实时曲线 |
ExtensionGateway | 接收 Marker、Interval、Scene、Custom Metric 与引擎数据 | ExtensionEvent | 影响基础采集成败 |
ClockSync | 保留设备/Host/Collector 原始时钟,估计映射、偏差与误差 | ClockSample → ClockModel | 覆盖原始时间戳 |
EventPipeline | 验证 Envelope、优先级背压、顺序/Gap、规范化、批量持久化 | SourceEvent → Raw/Metric/Quality Event | 把 unsupported/missing 写成 0 |
MetricRegistry | 定义 ID、scope、source、unit、methodVersion、转换和兼容规则 | MetricDefinition | 根据 UI 文案猜单位 |
AnalysisEngine | 区间统计、分位数、Frame/Jank、规则、基线和异常关联 | Raw Event + ModelVersion → Derived Event | 修改原始数据 |
SessionStore | append-only Chunk、索引、截图/日志/Trace、校验和、迁移 | Session Artifact | 把 HTML/CSV 当唯一事实源 |
Query/Chart | 窗口查询、极值保留下采样、十字线、区间联动、质量 Overlay | Query → Series/Annotation | 自行重新定义指标算法 |
ReportEngine | 离线 HTML、JSON 摘要、CSV、对比结论和证据链接 | Session + Analysis → Report | 省略质量/口径/样本不足 |
Canonical data contract
统一事件、指标和 Session 数据模型
事件 Envelope 最小字段
| 字段组 | 字段 | 说明 |
|---|---|---|
| 身份 | schemaVersion、eventId、sessionId、runId | 支持幂等、升级和多轮次 |
| 来源 | sourceId、collectorVersion、deviceId、processIdentity、generation | 进程重启后代际隔离 |
| 时钟 | sourceMonotonicNs、hostMonotonicNs、wallClockNs、clockModelId、clockErrorNs | 保留原始时钟和映射误差 |
| 序列 | sequence、priority、payloadType | 检测 Gap、乱序、重复和背压 |
| 质量 | status、ageNs、coverage、errorCode | OK/Stale/Missing/Unsupported/Error 不与数值混合 |
Metric Definition
每个指标必须定义 metricId、显示名、domain、scope、source、rawUnit、canonicalUnit、normalization、aggregation、methodVersion、supportedPredicate、expectedCadence、qualityPolicy。CPU 原始多核值与 normalized 值、GPU 0–1 与 0–100、Footprint 与 Resident 均使用不同字段或明确转换,禁止同名覆盖。
Session 目录
| 路径 | 内容 | 事实等级 |
|---|---|---|
manifest.json | 产品/Schema/设备/App/Collector/Xcode/模板/能力/时钟/结束原因 | 会话契约 |
events/*.pfevent | 分块、长度前缀 Protobuf、校验和、append-only 原始与标准事件 | 权威原始数据 |
index.sqlite | 时间范围、事件类型、Metric、Scene、Artifact 索引;WAL 写入 | 可重建索引 |
artifacts/ | 截图、日志、Crash/Jetsam、xctrace Trace、符号和诊断包 | 关联证据 |
analysis/ | 带 modelVersion 的派生指标、规则结果和比较结果 | 可重算 |
reports/ | 离线 HTML、JSON 摘要、CSV | 展示产物 |
Lifecycle and recovery
关键状态机
设备状态
disconnected → detected → trusted → developerReady → tunnelReady → available。任一步失败都保留可行动原因;重连后重新发布 capability snapshot。
Session 状态
draft → validating → preparing → recording → stopping → finalizing → completed,旁路状态为 degraded / failed / cancelled。崩溃重启后允许从持久化状态 Finalize。
Collector 状态
idle → starting → handshaking → streaming → recovering → stopped。每个 Collector 有重启预算、心跳超时、最后序列和最后错误。
进程绑定
bundle/executable → pid + startTime + generation。PID 消失后先发 ProcessEnded,再重绑并增加 generation;累计量不跨 generation 差分。
Product experience
产品信息架构与主流程
| 页面 | 用户任务 | 关键设计 |
|---|---|---|
| 设备中心 | 识别设备、信任/开发模式/tunnel、查看能力和故障 | 不只显示“在线”;展示 ready/degraded/unsupported 和修复动作 |
| 新建测试 | 选设备、App/进程、模板、指标、截图、时长、场景与重复轮次 | 预估开销和能力冲突;启动前生成不可变 SessionPlan |
| 实时监控 | 观察曲线、设备画面、Marker/Scene、进程重启、数据质量 | Overview + Track;十字线联动;Stale/Gap/重连直接覆盖在时间线 |
| Session 回放 | 缩放、区间统计、查看截图/日志/Trace、重新分析 | Detail + Inspector;任何结论可回到原始事件、单位和算法版本 |
| 对比实验 | 版本、机型、Run、场景和区间对比 | 只比较兼容口径;显示绝对值、相对变化、样本量和置信状态 |
| 报告中心 | 生成、归档、分享离线报告 | 摘要、异常、场景、曲线、质量、环境、方法版本和证据包 |
| 诊断中心 | 查看 Sidecar/Xcode/工具版本、哈希、日志和兼容矩阵 | 一键导出故障包;用户数据与工具诊断分目录 |
Non-functional requirements
可靠性、性能与验收目标
| 维度 | 首版目标 | 验证方式 |
|---|---|---|
| 会话稳定性 | 60 分钟基础会话无 writer failure;所有 Gap、重连和降级均显式记录 | 至少两代 iOS 路由、三轮压力与断连注入 |
| 数据完整性 | accepted = persisted;重复/乱序/sequence gap 有计数;异常退出可 Finalize | 事件压力、Host kill、磁盘满、Sidecar crash fixture |
| 采样延迟 | 1 Hz 基础指标 source→UI p95 ≤ 1.5 秒;不把延迟样本伪装成当前值 | 设备/Host 双时间戳与队列阶段测量 |
| 时间准确性 | 保留 device/host 原时钟;跨源映射误差可见;Frame 算法优先在同一设备时钟计算 | Clock round-trip、漂移与长会话实验 |
| 自身开销 | 以“不开采集”基线比较 Host CPU/内存、设备 CPU/FPS/能耗;阈值由 Gate 0 确认 | 静止、动画、压力三场景,每场景多轮置信区间 |
| 恢复 | 短暂断连自动进入 recovering;恢复后新 generation;超过预算明确 failed/degraded | 拔插、tunnel 重启、App 重启、设备锁屏 |
| 大数据交互 | 十万点 Session 首屏和缩放保持可操作;图表不加载全部原始事件到 UI | 查询窗口、极值保留下采样和内存基准 |
| 可迁移 | 旧 Session 原始事件不重写;索引与 Analysis 可重建;未知字段保留 | 至少两版 Schema 双向读取 fixture |
| 离线交付 | 采集、回放和 HTML 报告不依赖公网;Sidecar 版本、架构、签名和哈希可诊断 | 干净用户目录、源码目录移走、arm64/x86_64 分别验证 |
Stage gates
分阶段实施与严格门禁
| 阶段 | 交付范围 | 进入条件 | 退出条件 | 状态 |
|---|---|---|---|---|
| G0 真值与可行性 | 四类 Instruments Trace、DVT 候选对比、CPU/Memory/Frame/GPU 对照、开销与兼容矩阵 | 本方案获批并具备设备/样本 | 数据源、主采集器、口径和首版支持矩阵都有可复现证据 | 当前暂停点 |
| M1 iOS General MVP | 设备、App/进程、CPU/Memory/FPS 趋势/GPU、实时曲线、Marker、Session、回放、报告 | G0 全部通过 | 60 分钟稳定、断连/重启恢复、质量可见、离线安装验收 | 未开始 |
| M2 Frame Experience | FrameTime、Jank/BigJank/SmallJank、刷新率、Hitch 对照 | 逐帧 source 和算法 fixture 已确定 | 60/90/120Hz、动态刷新率和已知卡顿样本可复现、可解释 | 未开始 |
| M3 Automation & Compare | CLI、Local Service、CI 门禁、多设备租约、基线/场景/版本对比 | M1/M2 Schema 稳定 | 批量任务可取消/恢复;CI 返回明确状态和证据包 | 未开始 |
| M4 Deep & Extension | xctrace Trace、日志/Crash/Jetsam、GPU Counter、网络/能耗、SDK | Trace Schema 和时钟关联稳定 | 异常区间可关联栈、日志、场景和截图;增强失败不影响基础采集 | 未开始 |
| M5 Platform & Cloud | Android/PC/主机、团队/RBAC、私有部署、MCP/Skills/AI | iOS 产品与外部 API 经真实团队使用稳定 | 另立 ADR,不在本方案预先锁死实现 | 后置 |
Gate 0 evidence plan
当前暂停:Gate 0 还缺的关键证据
| 缺口 | 最小实验 | 决定什么 | 缺少时的处理 |
|---|---|---|---|
| Frame 原始数据源 | 60Hz/120Hz 的静止、滚动、动画、人工卡顿;Instruments Display/Frame Lifetimes/Hitches + DVT + PerfDog 同场 | FrameTime、FPS、Jank/SmallJank 的 source 与算法 | 首版只保留 FPS 趋势,不发布 Jank |
| 采集主实现 | pymobiledevice3 与 go-ios 在 iOS 16、17+、18+ 上比较建链、字段、延迟、断连、并发、60 分钟资源 | GeneralCollector 主/备实现 | 保持 Sidecar Contract,不在 Host 固化库 |
| CPU/Memory/GPU 口径 | 同一 App 场景对照 Xcode Gauge/Instruments、PerfDog 与 DVT raw | canonical unit、normalization 和 UI 名称 | 指标标记 Experimental,不进入门禁 |
| xctrace Schema | Time Profiler、Animation Hitches、Game Performance、Allocations 各固定 Trace/TOC/XPath | TraceAdapter 首版范围和版本键 | Deep Diagnosis 后置,不阻塞 M1 |
| 工具自身开销 | 不开采集、DVT 基础、截图、xctrace、Extension 分层对照 | 默认模板、采样率和开销提示 | 高开销能力默认关闭 |
| 产品行为基准 | PerfDog 当前版本的设备连接、新建测试、实时页、Marker/Scene、Session、对比、报告、错误状态录屏与样例 | 工作流对齐范围与可用性基线 | 先完成 Perfowl 自洽流程,不追像素级复制 |
Material request
建议你补充寻找的资料方向
- PerfDog 真实产品资料
当前桌面端完整操作录屏;设备/App/进程选择;实时曲线与十字线;Marker/Label/Scene;多轮测试;报告详情、对比和导出;断连、无权限、指标不支持等错误状态。最好附一份真实 Session 导出和报告。
- PerfDog Service / CLI 契约
当前帮助文档、命令输出、protobuf/API 定义、数据流样本、设备/任务状态码、多设备并行示例、网络模板和报告上传 Payload。已有官方 Demo 之外,优先找实际版本的接口说明。
- Apple Instruments 真机 Trace 样本
同一个测试 App 在 iOS 16、17、18+ 与 60/120Hz 设备上的 Time Profiler、Animation Hitches、Game Performance、Allocations Trace;每份样本记录 Xcode 版本、设备、系统、场景和时间点。
- 可控测试 App 与场景
准备一个可制造 CPU 峰值、内存增长/释放、主线程 50/100/200ms 阻塞、不同帧节奏、GPU 压力、网络吞吐与 App 重启的 fixture App;每个开关有确定时间和预期。
- DVT 原始事件样本
保存未归一化 Sysmontap、Graphics、Network、Energy/Core Profile 原始消息和属性列表,不只保存最终 CSV;覆盖首样本、空字段、进程重启、断连和 tunnel 重建。
- 目标支持矩阵
明确首版必须支持的 Mac 芯片、macOS、iPhone 型号、iOS 版本、刷新率、USB/Wi‑Fi、普通 App/游戏/App Extension,以及用户是否具备 Xcode。没有该矩阵,兼容范围会持续漂移。
Risk register
最高风险与控制方式
| 风险 | 概率/影响 | 控制 | 触发后的降级 |
|---|---|---|---|
| iOS 私有 DVT 协议随版本变化 | 高 / 高 | Adapter 隔离、capability snapshot、原始 fixture、双候选实现、兼容矩阵 | 明确 unsupported;保留 xctrace 深度模式 |
| Frame/Jank 算法与 PerfDog 不一致 | 高 / 高 | 同场真值、算法版本、公开公式 fixture、原始 Frame 保留 | 仅展示 Frame/FPS,不发布同名 Jank |
| 采集影响被测 App | 中 / 高 | 按能力标记开销等级;截图、Trace、Counter 分层开启;基线实验 | 自动切换 General Lite 模板 |
| xctrace/Xcode Schema 漂移 | 高 / 中 | TOC-first、版本化解析器、Trace fixture、原文件保留 | Trace 可打开但暂停结构化分析 |
| 长会话内存/磁盘膨胀 | 中 / 高 | Chunk、窗口索引、流式统计、保留策略、磁盘预算 | 停止高频 Artifact,基础事件继续并标记降级 |
| 双 Sidecar 技术栈维护成本 | 中 / 中 | Gate 0 只选一个主实现;统一协议;另一个只保留验证 Adapter | 移除备选,不影响 Session Schema |
| 过早建设云与 AI | 高 / 高 | M5 明确后置;每阶段由数据与用户证据进入 | 冻结平台层,回到指标和工作流 |
Approval boundary
本次建议批准的范围
本方案是架构与产品设计文件。没有新增采集代码、桌面端代码、Sidecar、数据库或产品构建产物。
设计依据
- client_perf iOS 专项分析 — 原型链路、长连接、任务和需要重做的边界。
- Codesign4QC 性能采集专项分析 — DVT、Schema v2、背压、质量、Session、Marker 与报告。
- Apple Instruments 专项调研 — Trace/Run、Template/Instrument、xctrace 和混合架构。
- Instruments 生态与 PerfDog 复刻差距 — 开源候选、PerfDog 能力地图和差距矩阵。
- Perfowl 调研与开发规则 — 先分析、批准后开发、HTML 归档和本地提交。