1、卡顿的本质:从视觉暂留到帧率
做前端性能优化这么多年,我经常被问到同一个问题:“为什么 60fps 就不卡,30fps 就明显感觉不流畅?”
这个问题看似简单,但真要讲清楚,得从人眼的生理构造说起。说白了,卡顿不是机器的感觉,是你眼睛和大脑的感知。今天我们就来彻底搞懂这件事。
1.1 视觉暂留:电影和屏幕的“骗术”
人眼有个很有意思的特性——视觉暂留。当一幅画面从眼前消失后,它在视网膜上的影像并不会立刻消失,而是会停留大约 1/24 到 1/16 秒。
我记得上学时老师做过一个实验:快速翻动一本画着连续动作的小册子,看起来就像动画片。这就是视觉暂留在起作用。
核心结论:只要画面切换速度足够快,人眼就会把一系列静态图像“脑补”成连续运动。这个临界点,就是帧率的理论基础。
电影行业很早就发现了这个规律。24fps(每秒 24 帧)是电影工业的标准,因为在这个速度下,人眼已经能感知到流畅的运动。但注意,电影每一帧都包含运动模糊,这降低了人眼对卡顿的敏感度。
而我们的屏幕呢?每一帧都是清晰锐利的静态画面。这就意味着,屏幕需要比电影更高的帧率,才能骗过你的眼睛。
1.2 帧率:屏幕刷新的“心跳”
屏幕刷新率,就是屏幕每秒钟重绘画面的次数,单位是 Hz。60Hz 的屏幕,每秒刷新 60 次,也就是 60fps。
你想想看,如果屏幕每秒只刷新 30 次,那每一帧的停留时间就是 33.3 毫秒。这个间隔,人眼已经能察觉到画面的跳跃感。而 60fps 的每一帧只有 16.7 毫秒,大脑就来不及“挑刺”了。
| 帧率 | 每帧时长 | 人眼感知 | 典型场景 |
|---|---|---|---|
| 24fps | 41.7ms | 可接受,有轻微卡顿感 | 电影(含运动模糊) |
| 30fps | 33.3ms | 能感知到卡顿 | 低端游戏、旧视频 |
| 60fps | 16.7ms | 流畅,无明显卡顿 | 标准屏幕、主流应用 |
| 120fps | 8.3ms | 极其流畅 | 高端手机、电竞显示器 |
我的经验:在项目中做性能优化时,我习惯把 60fps 作为“及格线”。只要帧率掉到 50fps 以下,用户就能感知到卡顿。别问我为什么是 50 不是 55——人眼就是这么敏感。
1.3 从视觉暂留到卡顿:一个完整的感知链路
卡顿的本质,其实是一个“预期 vs 现实”的落差。你的大脑根据之前的画面节奏,预判了下一帧应该出现的位置。如果屏幕没能在预期时间内刷新出那一帧,大脑就会发出“卡了”的信号。
我曾经在一个滚动列表优化项目中遇到过这种情况:页面在快速滚动时,帧率从 60fps 突然掉到 20fps,然后又恢复。用户反馈说“页面像在抽搐”。这就是典型的帧率抖动——比稳定低帧率更让人难受。
为什么会这样?因为大脑的预判被打破了。稳定 30fps 虽然慢,但节奏一致,大脑可以适应。而 60fps 突然掉到 20fps,就像你走路时突然踩空一个台阶——那种不适感非常明显。
避坑指南:我曾经以为只要平均帧率够高就行,结果被用户骂惨了。后来才明白,帧率稳定性比平均帧率更重要。一次掉帧的伤害,可能需要十帧流畅画面才能弥补。
1.4 屏幕刷新机制:从 GPU 到像素
要理解卡顿,还得知道屏幕是怎么工作的。简单来说,整个过程分三步:
- CPU 计算布局和绘制指令——确定每个元素的位置和样式
- GPU 栅格化——把绘制指令变成像素数据
- 屏幕刷新——把像素数据显示出来
这里面有个关键概念叫“垂直同步”(VSync)。屏幕的刷新是有固定节奏的,比如 60Hz 就是每 16.7ms 一次。如果 GPU 在屏幕刷新时还没准备好下一帧,屏幕就只能重复显示上一帧——这就是掉帧。
我习惯把屏幕刷新比作公交车发车:
- 公交车每 16.7 分钟发一班(VSync 信号)
- 如果乘客(GPU)没赶上这班车,就只能等下一班
- 等车的时间越长,用户感受到的卡顿就越明显
嗯,这个比喻虽然糙,但道理是一样的。
1.5 一张图看懂卡顿本质
下面这张 SVG 图,把整个感知链路串起来了。从人眼视觉暂留,到屏幕刷新机制,再到卡顿的最终感知——你一看就明白。
1.6 小结:卡顿的本质就一句话
好了,绕了这么大一圈,其实核心就一句话:
卡顿的本质 = 帧率不稳定 + 刷新节奏被打乱 + 人眼预期被打破
你想想看,是不是这个道理?稳定 30fps 虽然慢,但用户能接受;60fps 突然掉到 20fps,用户立刻骂娘。这就是因为大脑的预期被打破了。
我个人习惯在做性能优化时,先盯住帧率稳定性这个指标。平均帧率再高,只要有一次掉帧,用户体验就大打折扣。嗯,这个思路,后面几章我们会反复用到。