requestAnimationFrame 真的就比 setInterval setTimeout 好吗?
requestAnimationFrame 这个 API 已经出现很久了,网上也有很多相关文章,基本上都是说 requestAnimationFrame 有多好,是用来取代 setInterval setTimeout 的函数。
但是今天我就仔细思考了一下,这个 requestAnimationFrame 真的就那么好吗?
高刷屏的普及
随着科技的发展,60hz 刷新率已经不能满足部分用户的需求了,现在 90hz 120hz 144hz 165hz 各种刷新率的屏幕层出不穷,60hz 刷新率的屏幕似乎已经是落后显示器的代名词。
而前端开发在使用 requestAnimationFrame 实现动画的时候,很多开发者根本没有考虑高刷屏,这就导致了一个严重的问题:在高刷屏上动画速度严重高于预期。
作为一个游戏玩家记得有这样一个故事:一些很老的游戏在如今的电脑上运行,运行速度很很快,比如红警(当然,并不真的就是红警)在以前的老电脑上建造基地都是正常的等待时间,但在现在的电脑上就是刷刷刷的几十秒就啥都建好了,开始扔原子弹。因为这些游戏调用了系统 cpu 的时间,而随着 cpu 的更新,这个时间越来越快,所以现在的电脑上就会导致游戏速度加快很多倍。
如今这样的问题也出现在了浏览器上,随着高刷屏的普及,我们很可能会看到一些网站上的动画比预期的快了一倍,就是因为使用了 requestAnimationFrame 而没有做特殊的处理。。。
那么我们要怎样避免这个问题呢?只能在 requestAnimationFrame 中进行时间戳的判断。。。但是这又明显提高了开发动画的负担。甚至感觉不如直接用 setInterval 来得爽快,至少传入的间隔时间是相对稳定的,不同刷新率显示器上动画速度是差不多的。
requestAnimationFrame 这个 api 的设计,感觉更适合于 react 这样的需要根据屏幕刷新及时渲染的类库;或是显示时间这样的功能,屏幕每次刷新就获取一下当前时间。这样的功能才是越快越好,而动画是有个预期速度的,并不是越快就越好,但是这个 api 取的名字又像是用来做动画的。。。
requestAnimationFrame 的优点
- requestAnimationFrame 相比 setInterval 性能略有提高,可以避免一些多余的重绘,但是大部分情况下提升有限。
- requestAnimationFrame 在切换标签的时候会暂停,可以略微提升电脑的性能,但是这个性能对自身网页没啥影响(可能多个标签都有 setInterval 动画然后互相影响会导致性能问题吧)。
优点就这两个,第二点相对来说可能在极端情况对性能影响会比较大,但是我们也有可能不希望切换标签动画就暂停。
而最大的缺点就是不同刷新率的执行时间不统一,导致在做动画的时候还需要自行判断时间戳增加心智负担。
结论
所以可以看出,requestAnimationFrame 真没比 setInterval setTimeout 有绝对性的优势,requestAnimationFrame 感觉更适合用在需要更高效的输出最新信息的地方,而一些简单的动画用 setInterval 实现还会更快捷。就像我们没必要开发个两三个页面的简单网页就去搭一个 react,jQuery 一把梭不简单高效吗?
以上只是个人理解,欢迎探讨。