Jank、BigJank 与卡顿率说明

更新于 2026-08-25

PerfKitty 使用逐帧 FrameTime(帧耗时)识别画面卡顿,并提供 Jank、BigJank 和卡顿率(Stutter)指标。Android 与 iOS 使用相同的判定与统计方式,便于在不同设备和平台之间理解测试结果。

FrameTime 是什么

FrameTime 表示一帧画面从上一帧到当前帧所经历的时间,单位为毫秒(ms)。帧耗时越长,画面更新间隔越大,用户越容易感受到停顿或跳帧。

例如,在理想的 60 FPS 场景中,一帧大约需要 16.67 ms。如果某一帧突然耗时 100 ms,画面会较长时间没有更新,但是否记为 Jank 还需要同时结合前 3 帧的平均耗时判断。

Jank 判定

当前帧需要同时满足以下两个条件,才会被记为一次 Jank:

  1. 当前帧 FrameTime 大于前 3 帧平均 FrameTime 的 2 倍。
  2. 当前帧 FrameTime 大于 1000 / 24 × 2,约为 83.33 ms

可以写成:

当前帧 FrameTime > 前 3 帧平均 FrameTime × 2
并且
当前帧 FrameTime > 83.33 ms

第一项用于识别相对于近期画面节奏突然变慢的帧,第二项用于过滤绝对耗时较低、通常不构成明显卡顿的波动。两个条件必须同时成立。

BigJank 判定

当前帧需要同时满足以下两个条件,才会被记为一次 BigJank:

  1. 当前帧 FrameTime 大于前 3 帧平均 FrameTime 的 2 倍。
  2. 当前帧 FrameTime 大于 1000 / 24 × 3,即 125 ms

可以写成:

当前帧 FrameTime > 前 3 帧平均 FrameTime × 2
并且
当前帧 FrameTime > 125 ms

BigJank 表示更严重的长帧。满足 BigJank 条件的帧通常也满足 Jank 条件,因此可以把 BigJank 理解为 Jank 中较严重的一部分。

卡顿率如何计算

卡顿率用于表示整个测试期间有多少时间消耗在 Jank 帧上:

卡顿率(%)= 所有 Jank 帧的 FrameTime 之和 / 测试总时长 × 100%

例如,一次测试持续 10 秒,被判定为 Jank 的帧耗时分别为 100 ms130 ms200 ms

Jank 总耗时 = 100 + 130 + 200 = 430 ms
测试总时长 = 10 × 1000 = 10000 ms
卡顿率 = 430 / 10000 × 100% = 4.3%

这里的分母始终是完整测试时长,而不是只包含 Jank 的采样区间。测试时间越长且流畅区间越多,相同 Jank 总耗时对应的卡顿率就越低。

Jank 次数与卡顿率的区别

Jank 次数和卡顿率描述的是不同方面:

  • Jank 次数反映测试期间出现了多少个卡顿帧。
  • BigJank 次数反映其中有多少个帧属于更严重的长时间卡顿。
  • 每分钟 Jank/BigJank按测试时长归一化,适合比较时长不同的测试。
  • 卡顿率反映 Jank 帧占用了多少测试时间,同时考虑卡顿次数和每次卡顿的持续时间。

两次测试可能具有相同的 Jank 次数,但如果其中一次包含更长的 Jank 帧,它的卡顿率通常更高。分析性能问题时,建议同时查看次数、卡顿率、FrameTime 和 FPS 曲线。

测试与对比建议

  • 比较不同版本或设备时,尽量保持测试场景、操作步骤和测试时长一致。
  • 测试开始后应覆盖完整的目标场景,避免只截取发生卡顿的短区间,否则卡顿率会被放大。
  • 启动、切换场景、资源加载和网络等待可能产生长帧,应结合时间点和业务操作判断是否符合预期。
  • 某个平台或设备无法提供有效逐帧 FrameTime 时,Jank、BigJank 或卡顿率可能缺失;缺失值不应被理解为 0
  • 曲线中的单秒卡顿率用于定位问题发生的时间,概况中的卡顿率用于评价整场测试,两者的观察范围不同。