requestAnimationFrame请求动画帧
requestAnimationFrame是一个用于动画效果的 API,它使用浏览器的刷新率来执行回调函数,通常每秒钟执行60次(如果刷新率为120hz,则每秒执行120次),用法与setTimeout、setInterval很相似,但不需要设置时间间隔。requestAnimationFrame更适合用于实现动画效果,能够提供更好的性能和流畅度,而setTimeOut和setInterval则用
定义
requestAnimationFrame是一个用于动画效果的 API,它使用浏览器的刷新率来执行回调函数,通常每秒钟执行60次(如果刷新率为120hz,则每秒执行120次),用法与setTimeout、setInterval很相似,但不需要设置时间间隔。
特点
- 动画效果更流畅:requestAnimationFrame的执行跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,这样就不会引起丢帧现象,也不会导致动画出现卡顿的问题。(如果系统绘制率是 60Hz,那么回调函数就会16.7ms再 被执行一次,如果绘制频率是75Hz,那么这个间隔时间就变成了 1000/75=13.3ms)
- 更少的CPU、GPU和内存使用量:在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,且requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销
与setTimeout、setInterval对比

执行时机
setTimeout和setInterval的回调函数在指定的延迟之后执行,不考虑浏览器的渲染过程。requestAnimationFrame的回调函数会在浏览器下一次重绘之前执行,确保动画在浏览器的重绘间隔中执行,从而实现更流畅的动画效果。
性能优化
requestAnimationFrame在浏览器的重绘间隔内执行,可以最大程度上利用浏览器的优化,避免不必要的重绘,提高性能。setTimeout和setInterval则可能会在浏览器不需要重绘的时候执行,导致性能损耗。
暂停与恢复
使用requestAnimationFrame可以更容易地控制动画的暂停和恢复,因为可以通过控制是否调用requestAnimationFrame来实现。而setTimeout和setInterval需要额外的逻辑来实现暂停和恢复。
总结
requestAnimationFrame更适合用于实现动画效果,能够提供更好的性能和流畅度,而setTimeOut和setInterval则用于实现定时任务
代码示例
<body>
<div id="frameDiv">requestAnimationFrame</div>
<div id="setTimeoutDiv">setTimeout</div>
<div id="setIntervalDiv">setInterval</div>
<script>
let curFrameWidth = 0
let curTimeoutWidth = 0
let curIntervalWidth = 0
let animateFrame = undefined
let timeout = undefined
let interval = undefined
const maxWidth = 1024
const $frameDiv = $('#frameDiv')
const $setTimeoutDiv = $('#setTimeoutDiv')
const $setIntervalDiv = $('#setIntervalDiv')
// 使用 requestAnimationFrame()
function FrameAnimate(){
curFrameWidth = curFrameWidth + 3
$frameDiv.css('width', curFrameWidth)
if(curFrameWidth < maxWidth){
animateFrame = window.requestAnimationFrame(FrameAnimate) // 时间不用自己控制
}
}
// 利用setTimeout定时器,实现动画更新
function timeoutAnimate(){
curTimeoutWidth = curTimeoutWidth + 3
$setTimeoutDiv.css('width', curTimeoutWidth)
if(curTimeoutWidth < maxWidth){
timeout = setTimeout(timeoutAnimate, 16.7)
}
}
// 利用setInterval定时器,实现动画更新
function intervalAnimate(){
curIntervalWidth = curIntervalWidth + 3
$setIntervalDiv.css('width', curIntervalWidth)
if(curIntervalWidth >= maxWidth){
clearInterval(interval)
}
}
FrameAnimate()
timeoutAnimate()
interval = setInterval(intervalAnimate, 16.7)
</script>
</body>
更多推荐




所有评论(0)