再看最后一眼青春的星空

灿烂火光就像盛夏的烟火

欢送挣扎万年文明的巅峰

我们啊

将变星辰永远飘在黑暗宇宙

这个男人来自三体

Tirion

导航

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 的优点

  1. requestAnimationFrame 相比 setInterval 性能略有提高,可以避免一些多余的重绘,但是大部分情况下提升有限。
  2. requestAnimationFrame 在切换标签的时候会暂停,可以略微提升电脑的性能,但是这个性能对自身网页没啥影响(可能多个标签都有 setInterval 动画然后互相影响会导致性能问题吧)。

优点就这两个,第二点相对来说可能在极端情况对性能影响会比较大,但是我们也有可能不希望切换标签动画就暂停。
而最大的缺点就是不同刷新率的执行时间不统一,导致在做动画的时候还需要自行判断时间戳增加心智负担。

结论

所以可以看出,requestAnimationFrame 真没比 setInterval setTimeout 有绝对性的优势,requestAnimationFrame 感觉更适合用在需要更高效的输出最新信息的地方,而一些简单的动画用 setInterval 实现还会更快捷。就像我们没必要开发个两三个页面的简单网页就去搭一个 react,jQuery 一把梭不简单高效吗?

以上只是个人理解,欢迎探讨。

posted on 2021-10-20 11:59  Tirion  阅读(257)  评论(0编辑  收藏  举报

The Man from 3body