动画基础原理:帧率、刷新率与流畅度
做动画优化这么多年,我见过太多人一上来就调代码、改参数,结果折腾半天还是卡。为什么?因为连最基础的概念都没搞清楚。今天咱们就把地基打牢。
帧率(FPS)与刷新率(Hz)的区别
这两个词经常被混用,但本质完全不同。我刚开始带团队时,有个同事信誓旦旦地说「显示器 60Hz 就是每秒显示 60 帧」,这话对了一半,但漏了关键细节。
| 概念 | 定义 | 谁负责 | 典型值 |
|---|---|---|---|
| 帧率(FPS) | 应用/游戏每秒生成的画面数量 | CPU + GPU | 30、60、120、144 |
| 刷新率(Hz) | 显示器每秒刷新画面的次数 | 显示器硬件 | 60、90、120、144、240 |
说白了,帧率是「生产速度」,刷新率是「展示速度」。你游戏跑 200 FPS,但显示器只有 60 Hz,那实际你看到的还是每秒 60 个画面。反过来,显示器 144 Hz,但游戏只有 30 FPS,那画面照样一卡一卡的。
核心原则:流畅度由帧率和刷新率的较小值决定。两者差距越大,视觉撕裂或卡顿越明显。
人眼视觉暂留效应
为什么连续播放静态图片会感觉像在动?这得从生理结构说起。人眼视网膜上的感光细胞在受到光刺激后,信号不会立刻消失,而是会残留大约 1/16 到 1/24 秒。这个现象叫「视觉暂留」。
我记得早期电影就是利用这个原理——每秒 24 帧的胶片快速切换,人眼根本察觉不到中间的黑场。放到今天,24 FPS 勉强能看,但快速移动的场景就会模糊。为什么?因为每一帧之间的时间间隔太长,大脑不得不「脑补」中间的运动轨迹。
一个小实验:拿手机对着风扇拍慢动作视频,你会发现扇叶在某一帧是「静止」的。这就是帧率不够高,无法捕捉连续运动。动画优化同理——帧率太低,视觉暂留效应也救不了你。
动画流畅度的核心指标
判断一个动画是否流畅,不能光凭感觉。我习惯用三个量化指标来评估:
- 帧率稳定性(Frame Time Variance)——比平均帧率更重要。你跑 60 FPS,但每帧耗时忽高忽低,人眼照样觉得卡。我见过一个项目,平均帧率 58,但帧时间方差高达 8ms,用户反馈「看着头晕」。
- 丢帧率(Dropped Frame Ratio)——超过 16.67ms(60 FPS 的帧预算)就算丢一帧。丢帧率超过 5%,流畅度就会明显下降。
- 视觉卡顿次数(Jank Count)——连续两帧以上超过帧预算,算一次卡顿。Android 的 Choreographer 和 iOS 的 CADisplayLink 都能直接拿到这个数据。
避坑指南:我曾经只盯着平均 FPS 看,觉得 55 以上就 OK。结果用户反馈「滑动列表像在翻书」。后来一查帧时间曲线,发现每 10 帧就有一个 30ms 的尖峰。平均帧率骗了你,帧时间分布才是真相。
知识体系总览
下面这张图把本章的核心逻辑串起来了。你想想看,从「应用生成帧」到「显示器展示画面」,中间每一步都可能成为瓶颈。
实际项目中的经验
我参与过一个电商 App 的首页优化。当时列表滑动动画总是「肉肉的」,不跟手。排查后发现:
- 帧率稳定在 55-58 FPS,看起来还行
- 但帧时间曲线每隔 5-6 帧就有一个 25ms 的尖峰
- 原因是图片加载触发了主线程的同步解码
解决方案很简单:把图片解码放到子线程,预加载缓存。改完后帧时间方差从 6ms 降到了 1.2ms,用户反馈「终于顺滑了」。你看,问题不在平均帧率,而在帧时间的稳定性。
记住这个公式:流畅度 ≈ min(FPS, Hz) × 帧时间稳定性系数。两个因子缺一不可。