requestAnimationFrame学习

283 阅读1分钟

小巷.jpg 最近要做动画相关的需求,所以探究了一下raf,简单记录下

api概念理解

实现动画大概有两种思路:

  • css
  • js

如果我们使用js的话,又可以大致分为使用计时器,或者requestAnimationFrame

requestAnimationFrame就是为了解决计时器动画卡顿的问题的:

raf运行在js主线程中,相当于给浏览器的主线程生命周期里添加了个钩子(执行js =>执行raf回调函数=> 绘制),所以做到了与浏览器绘制频率一致;想对比计时器,计时器的时间是单独一个进程计算的,并且与主线程之间的任务存在执行的优先级顺序(宏任务微任务),自然做不到与绘制同频,所以会卡顿~

api使用理解

requestAnimationFrame(callback)执行之后,回调函数callback只会执行一次,并且执行时机是在下一次浏览器重绘之前,所以说:

  • 一般情况下没有必要保留requestAnimationFrame的返回值(没必要像计时器一样需要重视清除回调)
  • 如果callback的逻辑过于复杂,会阻塞浏览器主线程进行重绘,如下代码的执行效果:不停的打印@@@,但永远不会输出“下一帧开始执行了”
const test = () => {
  while(true) {
    console.log('@@@');
    requestAnimationFrame(() => {console.log('下一帧开始执行了')});
  }
}
requestAnimationFrame(test)

基于上面的理解,callback中的逻辑应该是一些会影响浏览器绘制的逻辑,比如修改元素的style,并且不能过于复杂