js中的requestAnimationFrame

文章类型:Javascript

发布者:hp

发布时间:2023-04-03

requestAnimationFrame 请求动画帧,它是一个浏览器的宏任务,主要是解决了定时器做动画时间间隔不稳定的问题

一:是什么

1:与settimeout很相似,只是不需要设置时间间隔而已。

2:使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用。

3:返回一个整数,表示定时器的编号,于取消这个函数的执行

二:特点

1:把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率,执行步伐跟着系统的绘制频率走。它能保证回调函数在屏幕每一次的绘制间隔中只被执行一次,不会引起丢帧,不会导致动画出现卡顿

2:在隐藏或不可见的元素中,不会进行重绘或回流,更少的CPU、GPU和内存使用量

3:由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,不激活状态,动画会自动暂停,有效节省了CPU开销

二:使用场景

1:页面滚动事件(scroll)的监听函数,推迟到下一次重新渲染,提升性能

$(window).on('scroll', function () {
window.requestAnimationFrame(scrollHandler)
})

2:大量数据渲染,通过ms来计算刷新率,得出每多少加载一次,渲染部分dom,避免卡顿

 function loop() {
if (countOfRender < loopCount) {
window.requestAnimationFrame(add);
}
}
loop();

3:监控卡顿方法,定时执行一些 JS 代码,如果浏览器卡顿,无法很好地保证渲染的频率,1s 中 frame 无法达到 60 帧,即可间接地反映浏览器的渲染帧率

var lastTime = performance.now()
var frame = 0
var lastFameTime = performance.now()
var loop = function (time) {
var now = performance.now()
var fs = now - lastFameTime
lastFameTime = now
var fps = Math.round(1000 / fs)
frame++
if (now > 1000 + lastTime) {
var fps = Math.round((frame * 1000) / (now - lastTime))
frame = 0
lastTime = now
}
window.requestAnimationFrame(loop)
}

四:总结

采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果