1. 卡顿与耗电调优核心指标:帧率、卡顿率、电池容量消耗、工具链总览
1.1 为什么必须先定义核心指标
在调优工作启动前,必须将“卡顿”和“耗电”量化为可复现、可对比的数值。主观感受无法作为优化依据,只有帧率、卡顿率、电池容量消耗这三大指标,才能支撑A/B测试与回归验证。本章逐一拆解它们的定义、采集手段与工具链全景。
调优第一准则:不要用“感觉”,要用数字。本章所有指标均可在开发/测试环境通过标准工具直接获取。
1.2 核心指标详解
| 指标 | 定义 | 计算方式 | 常用工具 | 参考健康值 |
|---|---|---|---|---|
| 帧率(FPS) | 每秒渲染的帧数,反映画面流畅度 | 总渲染帧数 / 运行时长 | dumpsys gfxinfo, Perfetto, FrameTiming | ≥ 55fps(60fps 目标) |
| 卡顿率(Stutter Rate) | 连续帧间隔时间差超过阈值(通常33ms)的比例 | 卡顿帧数 / 总帧数 × 100% | Choreographer, JankStats, Systrace | ≤ 5%(重度场景 ≤ 10%) |
| 电池容量消耗 | 单位时间内电池容量损耗,常用 mAh/h 或 %/h | 电池电压积分法 / 电量统计 | BatteryHistorian, dumpsys batterystats, PowerProfile | 游戏场景 ≤ 300mA 平均电流 |
1.3 帧率与卡顿率的深度辨析
帧率平均值并不代表体验良好——60fps 平均帧率下可能掩盖大量卡顿。必须同时观测 帧时间(Frame Time) 分布。以下命令可直接采集单帧耗时分布:
# 输出最近 120 帧的绘制时间(单位 ms)
adb shell dumpsys gfxinfo <package> framestats
# 解析 pipeline 阶段耗时
adb shell dumpsys gfxinfo <package> framestats | grep "PROFILE_DATA"
经验阈值:单帧耗时 > 16ms(60fps)即可被人眼感知;一旦出现连续 2 帧超过 32ms,卡顿感显著。JankStats 库内部采用“6ms 窗口”判断逻辑,但生产环境建议使用 33ms 硬阈值。
1.4 电池容量消耗的精确测量方法
应使用 BatteryHistorian 导出电量轨迹,而非依赖系统中“设定→电池”的模糊百分比。采集步骤:
- 重置电量统计:
adb shell dumpsys batterystats --reset - 开始测试场景(例如:连续滑动列表 5 分钟)。
- 导出原始数据:
adb bugreport bugreport.zip - 上传至
https://bathist.com或本地部署 BatteryHistorian 解析。
常见错误:不要同时连接 USB 充电线做长时间测试——USB 供电会掩盖真实放电电流。务必使设备处于纯电池放电状态(可短程以无线 ADB 或日志文件离线分析)。
1.5 工具链总览框架
调优工具链分为监控层、分析层、优化层。下图展示核心工具及其协作关系:
1.6 工具链快速入门命令
以下是最简命令集,建议每周进行至少一次基线采集:
# 帧率与卡顿率(需在测试前后分别执行)
adb shell dumpsys gfxinfo <package> | grep "Total frames rendered"
# 电池电流(需 root 或基于 BatteryHistorian)
adb shell dumpsys batterystats --charged <package>
# 录制 Systrace(分析长卡顿)
adb shell atrace --async_start -b 2048 gfx input view sched freq
# 操作后停止
adb shell atrace --async_dump > trace_output.systrace
# JankStats 集成(Kotlin 代码内)
# 在 Application 或 Activity 中初始化 JankStats 并回调统计
1.7 常见误区与调优起点
- 误区1:只优化 FPS 平均值,忽略帧率抖动(Frame Jitter)。
正确做法:同时关注 P95 帧时间和卡顿帧占比。 - 误区2:将电池消耗完全归咎于屏幕亮度或网络,忽略 App 后台唤醒锁。
正确做法:使用adb shell dumpsys batterystats --unplug查看各组件消耗排行。 - 误区3:在 USB 连接状态下测性能。
必须断开数据线(或使用无线 ADB),否则充电电流会严重干扰耗电数据。
起步建议:在一个简单的列表页面(例如 RecyclerView 展示 100 条数据)中,先采集 3 次基线数据,记录 FPS、卡顿率、电流。这就是你调优工作的“0 时刻”。后续每改动一处代码,立刻对比这个基线。任何导致 FPS 下降 2fps 或卡顿率上升 1% 的改动,都应重新审视。