2026-10-13 技术更新:本文原发表于 2019 年,以 60 Hz 设备解释帧节奏。60 FPS 不是所有 Android 设备的固定标准;旧文中的统一 16.67 ms 预算、帧率不匹配及功耗结论已在下文修正,并补充 Android 11 / API 30、Android 12 / API 31 起的适配与分析入口。
本文是 Systrace 系列文章的第三篇,解释一下为何大家总是强调 60 fps。这里的 FPS 指应用画面的帧率,Hz 指屏幕刷新率,两者统计的对象不同,可以参考这篇文章:新的流畅体验,90Hz 漫谈
本系列的目的是通过 Systrace 这个工具,从另外一个角度来看待 Android 的运行,从另外一个角度来对 Framework 进行学习。也许你看了很多讲 Framework 的文章,但是总是记不住代码,或者不清楚其运行的流程,也许从 Systrace 这个图形化的角度,你可以理解的更深入一些。
本文先分清帧率与刷新率,再讨论帧节奏、功耗和响应延迟。到了 90 Hz、120 Hz 设备上,仍需要让内容更新与显示时序配合,但不再把 60 FPS 或 16.67 ms 当成统一标准。
系列文章目录
- Systrace 简介
- Systrace 基础知识 - Systrace 预备知识
- Systrace 基础知识 - Why 60 fps ?
- Systrace 基础知识 - SystemServer 解读
- Systrace 基础知识 - SurfaceFlinger 解读
- Systrace 基础知识 - Input 解读
- Systrace 基础知识 - Vsync 解读
- Systrace 基础知识 - Vsync-App :基于 Choreographer 的渲染机制详解
- Systrace 基础知识 - MainThread 和 RenderThread 解读
- Systrace 基础知识 - Binder 和锁竞争解读
- Systrace 基础知识 - Triple Buffer 解读
- Systrace 基础知识 - CPU Info 解读
- Systrace 流畅性实战 1 :了解卡顿原理
- Systrace 流畅性实战 2 :案例分析: MIUI 桌面滑动卡顿分析
- Systrace 流畅性实战 3 :卡顿分析过程中的一些疑问
- Systrace 响应速度实战 1 :了解响应速度原理
- Systrace 响应速度实战 2 :响应速度实战分析-以启动速度为例
- Systrace 响应速度实战 3 :响应速度延伸知识
- Systrace 线程 CPU 运行状态分析技巧 - Runnable 篇
- Systrace 线程 CPU 运行状态分析技巧 - Running 篇
- Systrace 线程 CPU 运行状态分析技巧 - Sleep 和 Uninterruptible Sleep 篇
正文
今天来讲一下为何我们讲到流畅度,要首先说 60 帧。
我们先来理一下基本的概念:
- 60 FPS 表示每秒 60 帧,但要说明统计的是应用生成、提交还是最终呈现的帧。应用提交了 60 帧,不代表屏幕已经显示了 60 次独立的画面更新。
- 平均帧率相同,体验也可能不同。连续运动的画面需要尽量均匀地呈现;一会快、一会慢,会出现不稳定的运动节奏。
- 如果每秒均匀呈现 60 帧,两次新画面的间隔约为
1000 / 60 = 16.67 ms。这是目标间隔,不是“平均 60 FPS”自动满足的条件。
早期 Android 讲解常以 60 FPS 为目标,主要因为当时常用的 60 Hz 显示模式:希望每次刷新都有一帧按时准备好的新画面。这个例子有助于理解连续动画,但 Android 并不保证每次 Vsync 都产生新帧,静止页面也不需要为了凑满 60 FPS 持续重绘。
基本概念
FPS 描述内容帧率;Hz 描述显示刷新频率。在固定刷新模式下,60 Hz 的名义周期为 16.67 ms。设备可以支持多个刷新模式,实际使用哪个模式还受内容、系统策略和功耗条件影响,不能从面板标称“最高 120 Hz”推断当前一定是 120 Hz。Vsync 用来协调显示与渲染时序,也不意味着所有软件回调都在物理刷新瞬间执行。AOSP 多刷新率说明
| 固定刷新模式 | 名义刷新间隔 | 连续动画按每次刷新更新时的目标 |
|---|---|---|
| 60 Hz | 16.67 ms | 60 FPS |
| 90 Hz | 11.11 ms | 90 FPS |
| 120 Hz | 8.33 ms | 120 FPS |
| 144 Hz | 6.94 ms | 144 FPS |
这个表列的是 1000 / Hz。它不表示 Android 会每隔这些时间强制完整执行一次 measure、layout、draw,也不表示主线程、RenderThread、GPU、SurfaceFlinger 到屏幕呈现的所有工作都必须串行塞进同一个间隔。渲染可以流水化,具体一帧需要结合调度相位、截止时间、GPU 完成和呈现时间判断;只看主线程片段短于 16.67 ms,不能证明没有卡顿。
提高刷新率、同时提高内容帧率,通常意味着更多显示与渲染工作,但不能由此断言整机功耗随 Hz 线性增长。应用负载、分辨率、亮度、显示模式和设备实现都会影响结果。TFT 写入时序等屏幕设计约束也要结合具体面板讨论;功耗差异需要同设备、同场景测量。
效果提升
帧率和刷新率不同,不一定就会卡顿。稳定的 30 FPS 可以在 60 Hz 屏幕上让每帧持续两个刷新周期;60 FPS 也可以在 120 Hz 上按两个周期呈现一帧。内容帧数没有增加,但节奏可以均匀。反过来,即使平均值都是 60,如果提交和呈现时间不均匀,也可能看起来一顿一顿的。Android Frame Pacing 说明
对于同一段匀速运动,如果 30 FPS 和 60 FPS 都能稳定呈现,60 FPS 的新画面间隔从约 33.33 ms 缩短到 16.67 ms,相邻帧的运动位置变化也更小。但完整响应还包括输入、应用处理、排队和显示等环节,帧率翻倍不等于触控延迟必然减半。
原文的两个例子需要加上条件:
- 固定 75 Hz 显示 60 FPS 内容:75/60 不是整数,若采用重复帧匹配且不切换显示模式,就不能让每帧占用相同数量的刷新周期,可能产生节奏不均。不能简单概括成“完全没效果,只有费电”。
- 固定 30 Hz 显示 60 FPS 内容:每秒最多只有 30 次显示更新机会,无法完整呈现 60 次独立更新。但多余帧会被替换、丢弃还是让生产者等待,取决于缓冲队列和提交方式,不能一概说“恰好一半直接丢弃”。
更高刷新率也能改善低帧率内容的匹配。例如 24 FPS 视频在固定 60 Hz 下通常需要 3:2 重复节奏,而 120 Hz 可以让每个视频帧保持五个刷新周期,减少这类节奏不均。这不等于把视频变成了 120 FPS,也不说明电影和交互界面对延迟的要求相同。Android 帧率 API 说明
我当时给的体验建议是下面这一句,放在这里留个记录,不作为今天的购机推荐:
如果你想体验120hz 刷新率的屏幕,建议你试试 ipad pro ,用过之后你会觉得,60 hz 的屏幕确实有改善的空间。
原文列出的两个视频保留作历史延伸阅读,理解时也要区分内容帧率、显示节奏与交互延迟,不能从标题推导统一的流畅门槛:
下面保留原来的帧阶段图。图例包括 VSync、输入、动画、Traversal、Draw、Sync 和 Frame Completed 等标记,可辅助理解当时的渲染阶段:

这张图没有附原始 Trace、设备和 Android 版本,不能只凭颜色和柱高还原所有阶段的统计口径,也不能把它当成 GPU 独立执行时间或输入到屏幕的完整延迟。开发者选项中的 Profile GPU/HWUI rendering 也会随系统版本改变分段;其中的 16.67 ms 参考线针对 60 FPS,不是所有刷新模式的统一验收线。官方渲染检查说明
在现代 Android 上怎么检查
- 先确认目标节奏。 看当前实际刷新模式和内容目标帧率。静止页面、视频、游戏和连续滚动的目标不同;显示刷新率的浮层不能直接当作应用 FPS。
- 表达帧率意图。 Android 11 / API 30 起可以用
Surface.setFrameRate()告诉系统 Surface 的期望帧率,系统不保证采用请求值,这个调用也不会自动调整应用渲染循环。游戏可结合 Frame Pacing(Swappy)控制提交节奏,避免缓冲队列堆积带来的额外延迟。 - 检查实际帧与截止时间。 Android 12 / API 31 起可采集 FrameTimeline,结合 App 与 SurfaceFlinger 的 Expected/Actual Timeline、帧关联和线程调度分析。没有采到对应数据,不能解释成零卡顿;FrameTimeline 也不能单独替代完整的输入到显示延迟测量。
后续阅读可从 Perfetto 系列目录 或 高刷新率的优势与挑战 继续。
关于我 && 博客
下面是个人的介绍和相关的链接,期望与同行的各位多多交流,三人行,则必有我师!
- 博主个人介绍 :里面有个人的微信和微信群链接。
- 本博客内容导航 :个人博客内容的一个导航。
- 个人整理和搜集的优秀博客文章 - Android 性能优化必知必会 :欢迎大家自荐和推荐 (微信私聊即可)
- Android性能优化知识星球:付费社群已于 2026 年停止运营,不再招收新成员;此处保留历史介绍。
一个人可以走的更快 , 一群人可以走的更远
