帧率基础:FPS、视觉暂留与流畅标准
聊动画掉帧,第一个绕不开的概念就是帧率。说白了,帧率就是「每秒能刷多少张画面」。我见过不少新人一上来就追着问「怎么优化到 60fps」,但连帧率到底怎么算的都没搞清楚。这一章咱们就把地基打牢。
FPS 的定义与计算
FPS,全称 Frames Per Second,每秒传输帧数。你想想看,动画本质上是一张张静态图片快速切换。FPS 就是衡量这个切换速度的指标。
核心公式:
FPS = 1 / 单帧耗时(秒)
举个例子:如果渲染一帧花了 16.67ms,那 FPS = 1 / 0.01667 ≈ 60。
我在项目中遇到过不少同学,看到 Chrome DevTools 里显示 60fps 就觉得万事大吉。其实那个数字是「瞬时帧率」,可能只是某一秒的数据。真正的性能瓶颈往往藏在「帧耗时」里。
| 帧耗时 | 对应 FPS | 体验感受 |
|---|---|---|
| 8.33ms | 120 | 丝般顺滑(高刷屏) |
| 16.67ms | 60 | 流畅(标准) |
| 33.33ms | 30 | 轻微卡顿 |
| 50ms | 20 | 明显掉帧 |
| 100ms | 10 | 幻灯片体验 |
我的习惯:调试时别只看 FPS 数字,打开 Performance 面板看帧耗时火焰图。那个才暴露真实问题。
人眼视觉暂留——动画的生理基础
为什么连续播放静态图会产生「动」的感觉?这得感谢人眼的「视觉暂留」效应。简单说,图像在视网膜上会停留大约 1/24 秒(约 41.7ms)。
我记得大学时做实验,拿一个风扇,扇叶上画个点。转速慢时你能看到点在哪,转速一快,点就变成了一圈线。这就是视觉暂留在起作用——上一帧的残影还没消失,下一帧就来了,大脑自动帮你「脑补」成连续运动。
注意:视觉暂留不等于「人眼只能看到 24fps」。这是很多人的误区。视觉暂留决定了「最低连续感知」的阈值,但流畅度还跟画面刷新、运动模糊、大脑的视觉皮层处理速度有关。
实际上,人眼对帧率的敏感度远超 24fps。你想想看,电影院 24fps 你觉得流畅,那是因为有运动模糊。换成游戏 24fps,你马上觉得卡。为什么?因为游戏画面是「瞬时渲染」的,没有自然模糊来平滑过渡。
流畅动画的帧率标准
到底多少帧才算流畅?这个问题我从业十年,答案一直在变。
- 24fps:电影标准。靠运动模糊和固定快门角度撑起来的「伪流畅」。
- 30fps:早期主机游戏标准。能玩,但快速转动视角时能感到「顿挫感」。
- 60fps:Web 动画和现代游戏的标准。我个人认为这是「流畅」的底线。
- 90fps / 120fps:VR 和高刷屏需求。低于 90fps 的 VR 会让人头晕。
- 144fps+:电竞级。说实话,普通 UI 动画没必要追求这个。
我的建议:做 Web 动画,目标锁定 60fps 就够了。别盲目追高帧率,稳定比峰值更重要。我曾经优化过一个 H5 活动页,峰值能跑到 80fps,但每 3 秒掉一次到 20fps,体验反而更差。
帧率与掉帧的关系
掉帧,说白了就是「本该在 16.67ms 内完成的工作,没做完」。原因可能有很多:
- CPU 太忙:JavaScript 计算卡住了主线程。
- GPU 瓶颈:绘制指令太多,渲染管线堵了。
- 浏览器重排/重绘:布局抖动,强制同步布局。
- 垃圾回收:V8 引擎突然停下来收垃圾。
嗯,这里要注意:掉帧不是「丢帧」,而是「延迟交付」。浏览器不会真的扔掉一帧,而是让这一帧的显示时间变长,导致下一帧被推迟。结果就是画面「跳了一下」。
知识体系总览
下面这张图,我把帧率相关的核心概念串起来了。你看一眼,心里就有谱了。
避坑指南
最后分享几个我踩过的坑:
- 别信「60fps 就够」的绝对论:我曾经做一个滚动视差页面,60fps 稳如老狗,但用户反馈「眼睛累」。后来发现是帧耗时波动太大,虽然平均 60fps,但每帧耗时在 10ms~25ms 之间跳,人眼能感知到这种微小的节奏变化。
- 别忽略「帧生成时间」:Chrome 的 FPS 计数器是「显示帧率」,不是「渲染帧率」。有时候显示 60fps,但实际渲染只有 30fps——因为浏览器在重复显示上一帧。
- 高刷屏不是万能药:120Hz 屏幕确实能降低「每帧显示时间」,但如果你的动画逻辑本身就有问题,高刷屏只会让掉帧更明显——因为你有更多帧可以掉了。