requestAnimationFrame 和 setInterval 在动画上应用的区别

简介: 定义 requestAnimationFrame 帧动画,又叫 RAF,在 requestAnimationFrame 中执行的事件叫 RAF 回调 setInterval 引用 MDN 的定义 区别

定义

requestAnimationFrame

帧动画,又叫 RAF,在 requestAnimationFrame 中执行的事件叫 RAF 回调

setInterval

引用 MDN 的定义

WindowWorker 接口提供的 setInterval() 方法重复调用一个函数或执行一个代码片段,在每次调用之间具有固定的时间间隔。

它返回一个 interval ID,该 ID 唯一地标识时间间隔,因此你可以稍后通过调用 clearInterval() 来移除定时器。

区别

不同点

  1. requestAnimationFrame 会把每一帧中的所有 DOM 操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,一般来说,这个频率为每秒 60
  2. 在隐藏或不可见的元素中,requestAnimationFrame 将不会进行重绘或回流,这当然就意味着更少的的 cpu, gpu 和内存使用量
  3. setTimeout/setInterval 会造成丢帧,requestAnimationFrame 不会,有人测试过 setTimeout(callback, 0) 的执行时机为 4.7ms ,对于某些屏幕来说这太快了,就拿 60HZ 刷新率的屏幕来说,浏览器的刷新频率为每秒 60 帧,也就是 1000/60 = 16.7ms,浏览器在 16.7ms 的时候显示一帧,也就是浏览器会渲染一次,假设上面的 setTimeout 没有干扰,固定 4.7ms 执行一次,它执行 3 次以后,浏览器才会显示第 3 次的动画执行结果,前 2 次的运行没有意义,浏览器不会渲染也看不见,这个就是过度绘制导致丢帧,而 requestAnimationFrame 是根据帧数刷新的,它会在浏览器渲染前一点或者后一点执行(具体实现要看浏览器),它能保证动画可以根据浏览刷新率进行不会丢帧

    1. 丢帧的危害

      1. 动画断断续续显示
      2. 过度绘制会对电池使用寿命造成负面影响,并会降低其他应用的性能
  4. setTimeout/setInterval 会造成跳帧,requestAnimationFrame 不会,假设我们直到屏幕的刷新率并将其设置为 setTimeout/setInterval 的执行时间,但仍然会因为其不够精确,某一次的渲染可能会执行两次 setTimeout/setInterval 的回调,导致出现跳帧,requestAnimationFrame 因为是帧动画就不会有这个问题
  5. setTimeout/setInterval 有性能问题,requestAnimationFrame 不会,因为requestAnimationFrame是根据帧数刷新的,而 setInterval 是根据时间刷新的,也就是说 setInterval 在页面停止渲染,浏览器切换回后台后也是会继续执行,但实际上动画没有更新,因为页面已经停止渲染,而 requestAnimationFrame 只有在页面渲染的时候会执行

共同点

  1. requestAnimationFramesetInterval 都可能被阻塞,因为 JS 引擎和渲染引擎是互斥的,因此当存在大量 JS 计算时,setInterval 会因为前面的宏任务或者微任务执行过久而导致无法及时更新动画,而 requestAnimationFrame 是在渲染引擎执行时执行的,同样需要等待 JS 引擎执行结束

参考资料

  1. 来自requestAnimationFrame的灵魂拷问 - 自由的囚徒 - 知乎
  2. 【事件循环】【前端】事件原理讲解,超级硬核,忍不住转载
相关文章
|
1月前
|
前端开发 JavaScript UED
深入理解requestAnimationFrame函数及其应用
深入理解requestAnimationFrame函数及其应用
|
15天前
|
JavaScript 前端开发 安全
JavaScript基础-定时器:setTimeout, setInterval
【6月更文挑战第13天】JavaScript中的`setTimeout`和`setInterval`是异步编程的关键工具,用于按计划执行代码。`setTimeout`在延迟后执行一次,而`setInterval`则周期性执行。常见问题包括忘记清除定时器导致内存泄漏,递归使用`setTimeout`可能引发无限递归,以及字符串代码执行的安全隐患。解决方法包括使用`clearTimeout`和`clearInterval`,设置递归终止条件,以及优先使用函数表达式。理解定时器的非精确性并采用错误处理策略也是实践中的重要技巧。通过示例展示了如何延迟显示消息和周期性打印计数。
|
1月前
|
JavaScript 前端开发
JS实现可以控制的定时器,setInterval,clearInterval
JS实现可以控制的定时器,setInterval,clearInterval
26 0
|
1月前
|
前端开发 JavaScript API
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
|
6月前
|
JavaScript 前端开发
原生JavaScript之dom与setInterval/settimeout结合实现动画
原生JavaScript之dom与setInterval/settimeout结合实现动画
35 1
|
6月前
|
JavaScript 前端开发
window.setTimeout() 和window.setInterval() 的用法与区别
window.setTimeout() 和window.setInterval() 的用法与区别
35 0
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
257 0
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
使用requestAnimationFrame实现进度条
使用requestAnimationFrame实现进度条
133 0
15、计时器方法1(setInterval、clearInterval)
15、计时器方法1(setInterval、clearInterval)
111 0