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 导出电量轨迹,而非依赖系统中“设定→电池”的模糊百分比。采集步骤:

  1. 重置电量统计:adb shell dumpsys batterystats --reset
  2. 开始测试场景(例如:连续滑动列表 5 分钟)。
  3. 导出原始数据:adb bugreport bugreport.zip
  4. 上传至 https://bathist.com 或本地部署 BatteryHistorian 解析。
常见错误:不要同时连接 USB 充电线做长时间测试——USB 供电会掩盖真实放电电流。务必使设备处于纯电池放电状态(可短程以无线 ADB 或日志文件离线分析)。

1.5 工具链总览框架

调优工具链分为监控层、分析层、优化层。下图展示核心工具及其协作关系:

卡顿与耗电调优工具链全景图 监控层(数据采集) FrameTiming BatteryStats Choreographer Perfetto 分析层(指标计算) JankStats Systrace BatteryHistorian Profile GPU 优化层(行动决策) 代码重构 资源优化 渲染管线 功耗管理 关键说明: ● 监控层工具负责原始数据的采集,不处理指标计算,避免干扰被测进程。 ● 分析层将原始数据转换为帧率、卡顿率、mAh 值等业务指标,形成报告。 ● 优化层根据分析结果选择具体手段(如减少布局层级、异步化、限制后台唤醒等)。 典型调优目标的采集输出示例: FPS: 58.3 (持续列表滑动 60s) 卡顿率: 3.2% (共检测到 7 次卡顿/214 帧) 电池电流: 275 mA (WLAN 在线全亮屏) 温度变化: +2.3°C (10分钟稳定状态) 需要关注的红线: • 帧率 < 45fps → 明显卡顿,需优先排查 UI 线程 • 卡顿率 > 10% → 必须介入,大概率存在死锁/过度绘制 • 平均电流 > 350mA → 可能有过量唤醒锁或动画未优化 • 温度 > 40°C → 需检查算法层 CPU/GPU 负载

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% 的改动,都应重新审视。