帧率基础概念

帧率是衡量图形渲染性能的核心指标,直接决定用户视觉体验的流畅度。本章从帧率定义、刷新率、卡顿感知阈值三个基本维度建立分析基础,为后续使用 Android Studio Profiler 进行帧率诊断提供理论支撑。

帧率定义

帧率(FPS,Frames Per Second)指每秒渲染并显示的帧数。每帧由 CPU 处理(布局、绘制)、GPU 渲染(光栅化)和屏幕刷新三个阶段组成。帧率越高,画面越流畅。

关键公式: 帧率 = 1 / 每帧耗时(单位:毫秒)。例如:每帧耗时 16.67 ms 时,帧率为 60 FPS。

刷新率

刷新率(Hz)是屏幕硬件每秒钟刷新的次数,常见为 60 Hz、90 Hz、120 Hz。帧率应与刷新率匹配才能获得最佳体验:
当 FPS ≤ 刷新率时,显示设备以实际帧率输出;当 FPS > 刷新率时,多余帧会被丢弃(称为“帧撕裂”),此时需要开启垂直同步(VSync)来对齐。

概念 单位 含义 示例值
帧率(FPS) 帧/秒 应用生成并提交的帧速率 30、60、120
刷新率(Hz) 次/秒 屏幕物理刷新频率 60、90、120

卡顿感知阈值

用户对卡顿的感知与帧率下降程度直接相关。以下是业界公认的卡顿分级阈值:

  • 60 FPS 及以上:流畅无感知,单帧耗时 ≤ 16.67 ms
  • 30~59 FPS:轻微卡顿,用户能察觉到帧率波动,单帧耗时 16.67~33.33 ms
  • 20~29 FPS:明显卡顿,操作有滞后感,单帧耗时 33.33~50 ms
  • < 20 FPS:严重掉帧,界面接近冻结,单帧耗时 > 50 ms
Android 官方卡顿定义:当一帧渲染时间超过 16.67 ms(对应 60 Hz 刷新率),该帧即被视为“丢帧”(Jank)。丢帧数量超过总帧数的 10% 时,用户通常能感知到卡顿。

此外,帧率稳定性比平均帧率更重要。即使平均 FPS 达到 55,如果帧率频繁在 20~60 之间剧烈波动,体验仍会极差。Profiler 的帧率曲线能直观显示波动模式。

帧率与刷新率的关系图

下图展示了帧率、刷新率与用户体验之间的逻辑关系,以及丢帧和卡顿的触发条件:

帧率与刷新率关系图 帧率 (FPS) 刷新率 (Hz) 帧率 ≥ 刷新率? 流畅体验 丢帧 (Jank) 卡顿感知 单帧渲染耗时 > 16.67ms 即触发丢帧 丢帧累积 > 总帧数10% → 用户感知卡顿

使用 ADB 快速测量帧率

在 Android Studio Profiler 中分析前,可通过 adb 命令初步观察帧渲染数据:

adb shell dumpsys gfxinfo <package_name> framestats

该命令输出每帧渲染各阶段耗时(毫秒),例如:

Window: com.example.app
FrameStats:
    Total frames rendered: 235
    Number of janky frames: 42 (17.87%)
    90th percentile: 28.34ms
    95th percentile: 35.21ms
    99th percentile: 51.08ms

其中 janky frames 占比超过 10% 即进入卡顿区间,需进一步定位瓶颈。

常见误解:误以为“帧率必须等于刷新率”。实际上,当帧率持续高于刷新率时,垂直同步会强制丢弃多余帧,导致实际显示帧率被锁定在刷新率水平;当帧率低于刷新率时,显示的每一帧都可能因等待屏幕刷新而延迟,此时关注每帧耗时比平均 FPS 更有意义。

性能优化方向小结

  • 维持稳定帧率:通过 Profiler 定位单帧耗时峰值,重点优化 CPU/GPU 瓶颈。
  • 控制丢帧率 < 10%:利用 FrameMetrics API 采集自定义场景数据。
  • 适配高刷新率屏幕:在 90/120 Hz 设备上,每帧耗时需分别 < 11.11 ms 或 < 8.33 ms。