不使用onScroll如何实现更快的滚动?

3

读完了这篇文章,我对更快的滚动效果感到非常兴奋。于是我开始实现Warry的方法,看看与使用滚动事件监听相比是否能提高性能:

window.addEventListener('scroll', function() {
    console.log('Scrolling: ' + window.pageYOffset);
});

文章中的代码:

function loop() {
    if (lastPosition == window.pageYOffset) {
        requestAnimationFrame(loop);
        return false;
    } else lastPosition = window.pageYOffset;

    console.log('Scrolling: ' + window.pageYOffset);
    // make sticky calculations...

    requestAnimationFrame(loop);
}
loop(); // start loop

这两段代码输出相同的(Y)偏移量,从性能上看似乎等效。所以我的问题是:这篇文章是正确的吗?
此外,requestAnimationFrame如何适应这个情况?我知道它告诉浏览器希望执行重新绘制。或者... position fixed 是否是唯一可行的方式?我对这个主题很感兴趣,因为我正在开发一个粘性元素插件。
非常感谢您提供任何信息或建议!

“从性能上看似乎是等价的” - 你是怎么测量的? - Bergi
重点在于更高效的“效果”。如果你只是将日志记录到控制台,你不会感觉到任何区别(除了可能有不同数量的日志)。 - Bergi
每个tick的输出都是相同的。我还切换了Chrome DevTools上的所有渲染功能(Paint flashing,Layer borders,FPS meter和Scroll Performance Issues),以查看粘性元素的表现如何。没有任何明显的差异。我没有为此编写测试;只是好奇其他人能告诉我关于这个主题的更多信息。 - JasonK
1个回答

6

由于滚动事件可能会高频率触发,事件处理程序不应执行计算密集型操作,例如DOM修改。相反,建议使用requestAnimationFrame、setTimeout或customEvent来节流事件。

重要的是不仅要为您的动画使用requestAnimationFrame,还要以正确的方式使用它。 - html5rocks

还可以参见https://developer.mozilla.org/en-US/docs/Web/Events/scroll

这是一段很好的代码,可获得正确的浏览器前缀。如果不支持requestAnimationFrame,则会退回到setTimeout(function(){}, 0)

var requestAnimationFrame = window.requestAnimationFrame
    || window.webkitRequestAnimationFrame
    || window.mozRequestAnimationFrame
    || window.msRequestAnimationFrame
    || window.oRequestAnimationFrame
    || function(callback){ setTimeout(callback, 0) };

// Usage
window.addEventListener('scroll', function() {
    requestAnimationFrame(this.scroll); // call scroll event handler
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接