6.7 KiB
6.7 KiB
perf-1 基线测试指南与记录模板
更新时间:2025-09-09 12:25 +08
本文件用于后续进行盲盒主路径的性能基线采集与分析,包含目标范围、事件口径、采集步骤、分析方法、优化建议以及可直接填写的记录模板。
1. 目标与范围
- 场景 A(Image 盲盒):冷启动 → 准备(Unopened)→ 开启 → 展示图片
- 场景 B(Video 盲盒):冷启动 → 准备(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_AppearBlindBox_Status_UnopenedBlindBox_Status_PreparingBlindBox_Opening_BeginBlindBox_Opening_ShowMedia
- 视图模型(
wake/Features/BlindBox/ViewModel/BlindBoxViewModel.swift)BlindVM_Load_Begin/BlindVM_Load_EndBlindVM_Bootstrap_DoneBlindVM_Poll_Single_Yield/BlindVM_Poll_List_YieldBlindVM_Open(begin/end 包裹 openBlindBox 调用)
3. 指标口径(阶段耗时定义)
T_bootstrap = BlindBox_Appear → BlindVM_Bootstrap_DoneT_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/Profile(Xcode → Product → Scheme → Edit Scheme → Run = Release)
- 关闭调试开关(如 Metal API Validation)
5. 数据采集(Xcode Instruments)
- Xcode 菜单
Product → Profile,选择模板:- OS Signpost(主时间轴)
- Time Profiler(CPU/主线程占用)
- Core Animation(FPS 与掉帧)
- 选配:Network(若要看请求耗时)
- 运行路径:
- 场景 A(Image)
- 冷启动 App → 进入
BlindBoxView→ 等待状态到 Unopened → 点击开启 → 等待图片展示 → 停止录制
- 冷启动 App → 进入
- 场景 B(Video)
- 冷启动 App → 进入
BlindBoxView→ 等待状态到 Unopened → 点击开启 → 视频开始播放 → 停止录制
- 冷启动 App → 进入
- 场景 A(Image)
- 标注与导出:
- 在 OS Signpost 轨道上对齐事件(见第 2 节),测量 T_* 并记录
- 导出 A/B 两条 trace 作为基线归档
6. 可选 CLI(xctrace)
- 查看模板与设备:
xcrun xctrace list templates
xcrun xctrace list devices
- 采集 Time Profiler(将占位符替换为实际 Bundle ID):
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. 记录模板(直接复制并填写)
# perf-1 基线(日期:____ / 设备:____ / 系统:____ / 构建:Release)
## 场景 A(Image)
- 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) ____(____%)
- 结论与问题:
## 场景 B(Video)
- 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)与相关事件;若需要我直接提交“后台解码 + 细粒度埋点”的实现,请在下次迭代时告知,我会以最小改动提交补丁。