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. 【事件循环】【前端】事件原理讲解,超级硬核,忍不住转载
相关文章
|
4月前
使用requestAnimationFrame模拟实现setTimeout和setInterval
`rafTimeout` 函数采用 `requestAnimationFrame` 实现延时或周期性调用,提供与 `setTimeout` 和 `setInterval` 类似的功能。接受参数包括要执行的函数 `fn`、延迟时间 `delay`(默认 0ms)及是否周期执行 `interval`(默认为单次执行)。返回值为包含 `id` 的对象,可用于取消定时器。通过 `cancelRaf` 或 `cancelAnimationFrame` 方法可取消对应的 `rafTimeout` 定时器。
166 2
使用requestAnimationFrame模拟实现setTimeout和setInterval
|
5月前
|
JavaScript 前端开发 数据可视化
js 实现动画的两种方案对比:setTimeout vs RAF (requestAnimationFrame)
js 实现动画的两种方案对比:setTimeout vs RAF (requestAnimationFrame)
79 2
|
7月前
|
JavaScript 前端开发
JS实现可以控制的定时器,setInterval,clearInterval
JS实现可以控制的定时器,setInterval,clearInterval
50 0
|
7月前
|
前端开发 JavaScript API
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
2022年了!还在用定时器实现动画?赶紧试试requestAnimationFrame吧!
124 0
|
JavaScript 前端开发
原生JavaScript之dom与setInterval/settimeout结合实现动画
原生JavaScript之dom与setInterval/settimeout结合实现动画
71 1
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
324 0
手写系列 # 2:利用 requestAnimationFrame 实现 setInterval 计时器
使用requestAnimationFrame实现进度条
使用requestAnimationFrame实现进度条
165 0
|
移动开发 JavaScript 前端开发
解析requestAnimationFrame和requestIdleCallback
传统的javascript 动画是通过定时器 setTimeout 或者 setInterval 实现的。但是定时器动画一直存在两个问题
313 0
|
前端开发 小程序
09 React每隔0.2s颜色变淡 之settimeOut变成setInterval
09 React每隔0.2s颜色变淡 之settimeOut变成setInterval

热门文章

最新文章