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. 【事件循环】【前端】事件原理讲解,超级硬核,忍不住转载
相关文章
|
5月前
|
前端开发 JavaScript UED
深入理解requestAnimationFrame函数及其应用
深入理解requestAnimationFrame函数及其应用
|
4月前
|
JavaScript 前端开发 安全
JavaScript基础-定时器:setTimeout, setInterval
【6月更文挑战第13天】JavaScript中的`setTimeout`和`setInterval`是异步编程的关键工具,用于按计划执行代码。`setTimeout`在延迟后执行一次,而`setInterval`则周期性执行。常见问题包括忘记清除定时器导致内存泄漏,递归使用`setTimeout`可能引发无限递归,以及字符串代码执行的安全隐患。解决方法包括使用`clearTimeout`和`clearInterval`,设置递归终止条件,以及优先使用函数表达式。理解定时器的非精确性并采用错误处理策略也是实践中的重要技巧。通过示例展示了如何延迟显示消息和周期性打印计数。
57 2
|
2月前
使用requestAnimationFrame模拟实现setTimeout和setInterval
`rafTimeout` 函数采用 `requestAnimationFrame` 实现延时或周期性调用,提供与 `setTimeout` 和 `setInterval` 类似的功能。接受参数包括要执行的函数 `fn`、延迟时间 `delay`(默认 0ms)及是否周期执行 `interval`(默认为单次执行)。返回值为包含 `id` 的对象,可用于取消定时器。通过 `cancelRaf` 或 `cancelAnimationFrame` 方法可取消对应的 `rafTimeout` 定时器。
使用requestAnimationFrame模拟实现setTimeout和setInterval
|
3月前
|
JavaScript 前端开发 数据可视化
js 实现动画的两种方案对比:setTimeout vs RAF (requestAnimationFrame)
js 实现动画的两种方案对比:setTimeout vs RAF (requestAnimationFrame)
53 2
|
5月前
|
JavaScript 前端开发
JS实现可以控制的定时器,setInterval,clearInterval
JS实现可以控制的定时器,setInterval,clearInterval
38 0
|
5月前
|
前端开发 JavaScript API
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
102 0
|
JavaScript 前端开发
js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()
写在前面: 在js应用中,定时器的作用就是可以设定当到达一个时间来执行一个函数,或者每隔几秒重复执行某段函数。这里面涉及到了三个函数方法:setInterval()、setTimeout()、clearInterval(),本文将围绕这三种函数的用法,来实现定时器的功能,需要的朋友可以过来参考下,喜欢的可以点波赞,或者关注一下本人,希望对大家有所帮助。 定时器的应用需求: 1.设定一个时间,当时间到达的时候执行函数————比如:倒计时跳转页面等等。 2.每隔一段时间重复执行某段函数————比如抢票软件,比如设定500毫秒就重复刷新一次页面等等。 倒计时跳转实现demo:
609 0
js 定时器用法详解——setTimeout()、setInterval()、clearTimeout()、clearInterval()
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
297 0
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
使用requestAnimationFrame实现进度条
使用requestAnimationFrame实现进度条
152 0