帧率基础: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 内完成的工作,没做完」。原因可能有很多:

  1. CPU 太忙:JavaScript 计算卡住了主线程。
  2. GPU 瓶颈:绘制指令太多,渲染管线堵了。
  3. 浏览器重排/重绘:布局抖动,强制同步布局。
  4. 垃圾回收:V8 引擎突然停下来收垃圾。

嗯,这里要注意:掉帧不是「丢帧」,而是「延迟交付」。浏览器不会真的扔掉一帧,而是让这一帧的显示时间变长,导致下一帧被推迟。结果就是画面「跳了一下」。

知识体系总览

下面这张图,我把帧率相关的核心概念串起来了。你看一眼,心里就有谱了。

帧率基础 · 知识体系 帧率 (FPS) 定义:每秒帧数 FPS = 1 / 帧耗时 视觉暂留效应 约 1/24 秒残留 流畅标准 24 / 30 / 60 / 120 fps 瞬时 vs 平均帧率 运动模糊 vs 瞬时渲染 掉帧 = 延迟交付 核心结论 稳定 60fps 是 Web 动画的黄金标准 掉帧的本质是单帧耗时超过 16.67ms

避坑指南

最后分享几个我踩过的坑:

  • 别信「60fps 就够」的绝对论:我曾经做一个滚动视差页面,60fps 稳如老狗,但用户反馈「眼睛累」。后来发现是帧耗时波动太大,虽然平均 60fps,但每帧耗时在 10ms~25ms 之间跳,人眼能感知到这种微小的节奏变化。
  • 别忽略「帧生成时间」:Chrome 的 FPS 计数器是「显示帧率」,不是「渲染帧率」。有时候显示 60fps,但实际渲染只有 30fps——因为浏览器在重复显示上一帧。
  • 高刷屏不是万能药:120Hz 屏幕确实能降低「每帧显示时间」,但如果你的动画逻辑本身就有问题,高刷屏只会让掉帧更明显——因为你有更多帧可以掉了。