关于JavaScript的requestAnimationFrame
已经有很多问题,并且(我认为)我理解了这个概念,但是在这种情况下,使用和不使用cancelAnimationFrame
之间在性能上有什么区别吗?
// Setup a timer
var timeout;
// Listen for resize events
window.addEventListener('scroll', function () {
console.log( 'no debounce' );
// Cancel last animation, if there's one
if (timeout) {
window.cancelAnimationFrame(timeout);
}
// Setup the new requestAnimationFrame()
timeout = window.requestAnimationFrame(function () {
// Run our scroll functions
console.log( 'debounced' );
});
}, false);
没有cancelAnimationFrame
:
// Setup a timer
var timeout;
// Listen for resize events
window.addEventListener('scroll', function () {
console.log( 'no debounce' );
// Setup the new requestAnimationFrame()
window.requestAnimationFrame(function () {
// Run our scroll functions
console.log( 'debounced' );
});
}, false);
在每个代码上我得到相同的结果。
但是我想知道如果不取消动画帧会发生什么。请求的函数是否堆积在内存中的某处?
答案 0 :(得分:0)
var isRafLogged = false;
function rafCb(now) {
if (isRafLogged) {
console.log('rAF callback executed at: ', now, 'ms');
}
requestAnimationFrame(rafCb);
}
function onWindowScroll() {
// when in scroll, log aforescheduled rAF() only when in scroll
isRafLogged = true;
const now = performance.now();
console.log('scroll callback executed at: ', now, 'ms');
// when out of scroll, stop logging the rAF
setTimeout(function() {
isRafLogged = false;
});
}
requestAnimationFrame(rafCb);
window.addEventListener('scroll', onWindowScroll);
html,
body {
height: 10000px;
}
p {
font-size: 200px;
writing-mode: vertical-lr;
}
<p>.....................................................................................................................................................................................................................................................................................................................................................................</p>
如果我们在requestAnimationFrame
的同时安排连续的scroll
循环,我们将清楚地看到rAF
和scroll
回调正在发生
每个VSync event最多一次。
因此回到您的主要问题
在这种情况下,带有和不带有cancelAnimationFrame的性能是否有区别?
通常不,因为您的requestAnimationFrame()
调用阻止了下一个scroll
回调,并且您执行的滚动回调不能超过请求的帧回调,因此存在1对1的相关性,因为它们两者都每帧渲染最大发生一次。
但是我想知道如果不取消动画帧会发生什么。请求的函数是否堆积在内存中的某处?
所有请求的动画帧回调都堆积在callbacks的内部池中,在最近的Vsync事件之前将其刷新。因此,从技术上讲,是删除计划的回调的唯一方法是cancelAnimationFrame()
,但这又与您的情况无关,因为您的requestAnimationFrame()
回调发生在窗口scroll
回调的“相同”时间
希望有道理。