wake-ios/specs/perf_baseline.md

150 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# perf-1 基线测试指南与记录模板
更新时间2025-09-09 12:25 +08
本文件用于后续进行盲盒主路径的性能基线采集与分析,包含目标范围、事件口径、采集步骤、分析方法、优化建议以及可直接填写的记录模板。
---
## 1. 目标与范围
- 场景 AImage 盲盒):冷启动 → 准备Unopened→ 开启 → 展示图片
- 场景 BVideo 盲盒):冷启动 → 准备Unopened→ 开启 → 播放视频
- 输出关键阶段耗时T_*)、帧率/掉帧、CPU 热点、潜在瓶颈与改进建议
## 2. 现有埋点OS Signpost
Perf 工具位于 `wake/Core/Diagnostics/Performance.swift``subsystem: app.wake``category: performance`)。以下事件可在 Instruments 的 OS Signpost 中看到:
- 视图(`wake/Features/BlindBox/View/BlindBoxView.swift`
- `BlindBox_Appear`
- `BlindBox_Status_Unopened`
- `BlindBox_Status_Preparing`
- `BlindBox_Opening_Begin`
- `BlindBox_Opening_ShowMedia`
- 视图模型(`wake/Features/BlindBox/ViewModel/BlindBoxViewModel.swift`
- `BlindVM_Load_Begin` / `BlindVM_Load_End`
- `BlindVM_Bootstrap_Done`
- `BlindVM_Poll_Single_Yield` / `BlindVM_Poll_List_Yield`
- `BlindVM_Open`begin/end 包裹 openBlindBox 调用)
## 3. 指标口径(阶段耗时定义)
- `T_bootstrap = BlindBox_Appear → BlindVM_Bootstrap_Done`
- `T_ready = 首次出现 BlindBox_Status_Unopened`(或 `.Preparing → .Unopened` 的跃迁)
- `T_open_api = BlindVM_Open(begin) → BlindVM_Open(end)`(开盒 API 往返)
- `T_open_anim = BlindBox_Opening_Begin → BlindBox_Opening_ShowMedia`(动画到媒体展示)
- `T_prepare_media`(建议新增埋点后再测,见第 7 节)
建议阈值(参考):
- Image`T_bootstrap ≤ 800ms``T_prepare_media ≤ 300ms`
- Video`T_bootstrap ≤ 1200ms``首帧可播放 ≤ 1.0s`
- Core Animation每 1 秒内掉帧 < 3主线程占用峰值 < 80%
## 4. 环境与准备
- 设备实体机建议 iPhone 13 及以上保持温度和电量稳定
- 构建Release/ProfileXcode Product Scheme Edit Scheme Run = Release
- 关闭调试开关 Metal API Validation
## 5. 数据采集Xcode Instruments
1) Xcode 菜单 `Product → Profile`选择模板
- OS Signpost主时间轴
- Time ProfilerCPU/主线程占用
- Core AnimationFPS 与掉帧
- 选配Network若要看请求耗时
2) 运行路径
- 场景 AImage
- 冷启动 App 进入 `BlindBoxView` 等待状态到 Unopened 点击开启 等待图片展示 停止录制
- 场景 BVideo
- 冷启动 App 进入 `BlindBoxView` 等待状态到 Unopened 点击开启 视频开始播放 停止录制
3) 标注与导出
- OS Signpost 轨道上对齐事件见第 2 测量 T_* 并记录
- 导出 A/B 两条 trace 作为基线归档
## 6. 可选 CLIxctrace
- 查看模板与设备
```bash
xcrun xctrace list templates
xcrun xctrace list devices
```
- 采集 Time Profiler将占位符替换为实际 Bundle ID
```bash
xcrun xctrace record \
--template "Time Profiler" \
--output "~/Desktop/wake_timeprofiler.trace" \
--launch com.your.bundle.id
```
## 7. 分析方法
- OS Signpost筛选 `subsystem = app.wake``category = performance`沿时间轴读取 T_*。
- Time Profiler关注主线程热点Lottie 渲染SVG 绘制SwiftUI 布局图片解码AVAsset 初始化等)。
- Core Animation查看帧时间直方图与掉帧分布对应时间截面回到 Time Profiler 交叉验证 CPU 热点
## 8. 建议新增埋点(便于下一轮更精细分析)
- `prepareMedia()``BlindBoxViewModel`中增加 begin/end
- 图片`BlindVM_PrepareMedia_Image`
- 视频`BlindVM_PrepareMedia_Video`
- `BlindBoxView` 的开启动画链路如需更细可在 `BlindBox_Opening_Begin → BlindBox_Opening_ShowMedia` 之间插入阶段性事件例如某帧/进度阈值)。
## 9. 常见瓶颈与建议
- 图片解码在主线程
- 现状`prepareMedia()` 标注了 `@MainActor``UIImage(data:)` 可能阻塞主线程
- 建议使用后台队列/`Task.detached(priority: .userInitiated)` 解码回主线程赋值或使用 `CGImageSource` 增量解码
- AVAsset 初始化与尺寸计算
- 建议使用异步属性加载 `await asset.load(.tracks)`后台计算宽高比后再回主线程设置
- Lottie 渲染
- 建议仅在可见时播放当前已实现检查 JSON 体量与层数必要时优化资源
- SVG 渲染
- 建议大面积静态背景预栅格化为 PNG交互区域保留矢量或增加缓存层
- OnBoarding 去重
- 现状 `uiImage.pngData()` 做去重计算较重
- 建议改用轻量哈希缩略图 + 平均哈希/pHash或文件 URL/尺寸 + 字节总量近似判重
- 网络与缓存
- 建议图片设置合理 `URLCache`视频首帧使用低码率预览或占位图降低等待感网络层收集 `URLSessionTaskMetrics` RTT/吞吐量观测
## 10. 记录模板(直接复制并填写)
```markdown
# perf-1 基线日期____ / 设备____ / 系统____ / 构建Release
## 场景 AImage
- T_bootstrap____ ms
- T_ready____ ms
- T_open_api____ ms
- T_open_anim____ ms
- T_prepare_media若有____ ms
- Core Animation平均 FPS / 掉帧____ / ____
- Time Profiler 热点(主线程 Top3
- 1) ________%
- 2) ________%
- 3) ________%
- 结论与问题:
## 场景 BVideo
- T_bootstrap____ ms
- T_ready____ ms
- T_open_api____ ms
- T_open_anim____ ms
- T_prepare_media若有____ ms
- Core Animation平均 FPS / 掉帧____ / ____
- Time Profiler 热点(主线程 Top3
- 1) ________%
- 2) ________%
- 3) ________%
- 结论与问题:
## 归纳与下一步
- 瓶颈总结:
- 优化优先级P0/P1/P2
- 行动项:
```
## 11. 下次继续(执行清单)
- 采集 A/B 1 trace 并填写第 10 节模板
- 可选 `prepareMedia()` 增加图片/视频的 begin/end 埋点
- 将图片解码移至后台线程回主线程赋值
- 使用 AVAsset 异步加载 track/时长并后台计算尺寸
- 检查 Lottie/SVG 资源与渲染负载必要时优化
- 调整 OnBoarding 去重逻辑避免 `pngData()` 重计算
- 配置 `URLCache` 与视频首帧占位方案
---
附注本指南依赖现有 `Perf` 工具`Performance.swift`与相关事件若需要我直接提交后台解码 + 细粒度埋点的实现请在下次迭代时告知我会以最小改动提交补丁