通常情况下,一秒会有60帧,也就是浏览器一秒将页面画60遍,就像这样,一个红线代表一次绘制

使用setInterval并将间隔设为1000/60可以做出动画效果:每隔1000/60秒就进行一次动画计算

动画计算后就可以让浏览器在下一帧将它绘制出来,就像这样,一个黑图钉代表一次计算

但这只是理想情况,实际上渲染帧不会分布太平均,也许机器配置不行,也许电脑刚好卡了

结果这下坏了,出现了空帧和跳帧

空帧会使两次渲染帧里什么都没做,造成浪费,而跳帧使两次渲染帧内出现了两次动画计算,跨度过大

空帧和跳帧很可能会同时出现,这导致动画变得不连续,出现卡顿

但更哈人的是,这还不是最糟的,setInterval自己也不会分布得平均,真实情况很有可能是这样的

跳帧和空帧会频繁出现,抖动和卡顿很可能会扎堆

requestAnimationFrame就解决了setInterval的问题,它是更好的实现动画的方案

它接收一个函数,告诉浏览器:渲染下一帧的时候运行一下我这个动画计算函数

但它只会执行一次,如果需要每一帧前都运行一次即实现连续的动画,就需要递归调用

1
2
3
4
5
6
const raf = ()=> {
requestAnimationFrame(()=> {
animation() // 动画
raf() // 继续执行下一帧
})
}

虽然它仍然不能解决渲染帧不平均的问题,但它能保证每一次动画计算对应一帧

不会出现跳帧和空帧,动画这下流畅多了!