4. 性能指标:FPS、帧时间、帧间隔、Jank率、卡顿率

做双缓冲优化,你得先知道怎么衡量效果。不然你改了一堆代码,到底是变好了还是变差了?全靠感觉可不行。

我个人习惯,先把这几个核心指标刻在脑子里。它们就像汽车的仪表盘——FPS 是时速表,帧时间是油耗表,Jank 率是故障灯。每个指标都有自己的脾气,咱们一个一个说。

4.1 FPS(每秒帧数)—— 最熟悉的陌生人

FPS,全称 Frames Per Second。说白了就是一秒钟能刷多少帧画面。60 FPS 意味着每 16.67ms 就要出一帧。

很多人觉得 FPS 越高越好。嗯,这话对了一半。但你要注意,FPS 是个平均值。我在项目中遇到过这种情况:某款手机游戏跑基准测试,平均 FPS 显示 58,但玩家就是觉得卡。为什么?因为 FPS 把「卡顿」给平均掉了。

核心认知:FPS 只能反映整体吞吐量,无法体现单帧的抖动。一个 58 FPS 的系统,可能前 59 帧都流畅,第 60 帧突然卡了 500ms——但平均下来还是 58。

所以,别只看 FPS。它是个好指标,但不是唯一指标。

4.2 帧时间(Frame Time)—— 真正的硬指标

帧时间,就是渲染一帧实际花了多少毫秒。这个指标比 FPS 诚实得多。

你想想看,如果一帧花了 30ms,那就算你 FPS 算出来是 33,用户照样觉得卡。因为人眼对「突然的停顿」极其敏感。

帧时间范围 用户体验 我的判断
< 8ms 丝滑流畅(120Hz 屏) 优秀,不用动
8ms ~ 16ms 流畅(60Hz 屏) 合格,可优化可不优化
16ms ~ 33ms 轻微感知卡顿 需要排查
> 33ms 明显卡顿 必须优化

我的习惯:抓帧时间曲线时,我只看 P99 和 P95 分位值。平均值骗人,但极端值不会。如果 P99 帧时间超过 30ms,说明有 1% 的帧在严重拖后腿——这 1% 就是用户骂娘的原因。

4.3 帧间隔(Frame Interval)—— 抖动的显微镜

帧间隔,是相邻两帧之间的时间差。它和帧时间有点像,但关注点不同。

帧时间看的是「这一帧画了多久」,帧间隔看的是「两帧之间隔了多久」。如果帧间隔忽大忽小,说明系统在「一抖一抖」地输出画面。

举个例子:

理想情况:16ms, 16ms, 16ms, 16ms  → 间隔稳定
抖动情况:16ms, 32ms, 8ms, 24ms   → 间隔剧烈波动

第二种情况,平均帧间隔还是 16ms,但用户已经晕了。我曾经调试一个视频播放器,帧时间一直很稳,但播放就是一顿一顿的。后来一查帧间隔,发现是 VSync 信号和渲染线程不同步导致的——帧间隔在 16ms 和 48ms 之间来回跳。

避坑指南:我曾经以为帧时间稳定就万事大吉。直到有一次,帧时间稳定在 15ms,但帧间隔却出现了 50ms 的毛刺。原因是双缓冲的 SwapBuffer 调用被一个高优先级线程打断了。所以,帧间隔和帧时间要一起看,缺一不可。

4.4 Jank 率 —— 卡顿的「定罪率」

Jank,这个词在 Android 圈用得比较多。它指的是「一帧的渲染时间超过了预期 deadline」。对于 60Hz 屏幕,deadline 就是 16.67ms。超了,就算一次 Jank。

Jank 率的计算公式很简单:

Jank 率 = (Jank 帧数 / 总帧数) × 100%

比如你跑了 1000 帧,其中有 50 帧超时了,那 Jank 率就是 5%。

我个人觉得,Jank 率比 FPS 更能反映「卡顿感」。因为 FPS 可能被大量正常帧拉高,但 Jank 率直接告诉你「有多少帧是坏的」。

一般业界标准:

  • 优秀:Jank 率 < 1%
  • 良好:Jank 率 1% ~ 3%
  • 需优化:Jank 率 3% ~ 5%
  • 严重:Jank 率 > 5%

4.5 卡顿率 —— 用户的真实感受

卡顿率和 Jank 率不一样。Jank 率是「技术上的超时」,卡顿率是「用户感知到的卡顿」。

怎么定义「用户感知到卡顿」?一般有两种做法:

  1. 连续 Jank 检测:如果连续 3 帧以上都 Jank,用户大概率会注意到。
  2. 帧间隔阈值法:如果帧间隔超过某个阈值(比如 50ms),就算一次卡顿。

我在项目中更倾向于第二种。因为连续 Jank 检测有个问题:如果每两帧 Jank 一次,但从不连续,用户其实不太敏感。反而是那种「突然卡住 100ms 不动」的情况,用户立刻就能感觉到。

我的经验公式:卡顿率 = (帧间隔 > 50ms 的帧数 / 总帧数) × 100%。50ms 这个阈值是我在多个项目里试出来的,低于 50ms 的抖动人眼还能接受,超过 50ms 基本一抓一个准。

4.6 指标之间的关系 —— 一张图说清楚

这几个指标不是孤立的。它们从不同角度描述同一个问题:画面流畅度。我画了张图,帮你理清它们的关系。

性能指标关系图 渲染管线 FPS(每秒帧数) 帧时间(Frame Time) 帧间隔(Frame Interval) Jank 率(超时比例) 卡顿率(用户感知) 指标使用建议 • 日常监控:优先看帧时间 P99 和 Jank 率 • 问题定位:帧间隔 + 帧时间一起抓,找抖动根因 • 用户反馈:卡顿率比 FPS 更能解释「为什么用户说卡」

4.7 实战中怎么用这些指标

光知道定义没用,得会用。我分享几个实战场景。

场景一:新功能上线,怕引入卡顿

我会在灰度阶段埋点,采集帧时间和 Jank 率。如果 Jank 率从 0.5% 涨到 2%,立刻回滚。别犹豫,2% 的 Jank 率在线上就是灾难。

场景二:用户反馈「偶尔卡一下」

这种最头疼。因为不是持续卡,是偶发。我会让客户端把帧间隔超过 50ms 的帧前后各 5 帧都打日志。这样能抓到「卡顿现场」的上下文。我曾经靠这个办法抓到过一个第三方 SDK 在后台做网络同步导致的卡顿。

场景三:竞品对比

别只比 FPS。我一般比三个指标:P99 帧时间、Jank 率、卡顿率。如果竞品 FPS 比你高 5,但 Jank 率比你高 3%,那说明它的高 FPS 是靠「牺牲稳定性」换来的——用户实际体验不一定比你好。

小技巧:做性能报告时,把 FPS 和 Jank 率放在同一张图上。用柱状图展示 FPS,用折线图叠加 Jank 率。这样一眼就能看出「高 FPS 是不是靠运气换来的」。

4.8 总结一下

这五个指标,我按优先级排个序:

  1. 帧时间(P99)—— 最诚实,最直接
  2. Jank 率—— 技术上的卡顿比例
  3. 卡顿率—— 用户感知的卡顿比例
  4. 帧间隔—— 排查抖动问题的利器
  5. FPS—— 看看就好,别太当真

记住,指标是工具,不是目的。我们的目的是让用户觉得「流畅」。下次你拿到一份性能数据,别只看 FPS 漂不漂亮,把帧时间曲线拉出来看看——那才是真相。