JasonK
JasonK

Reputation: 5294

Faster scrolling without onScroll?

I was getting really excited after reading this article about faster scroll effects. I went implementing Warry's method to see if I could spot any difference in performance - compared to using the scroll event listener:

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

Code from article:

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

These two pieces of code output the same (Y)offset and seem to be equivalent performance-wise. So my question is: Is the article right?

Also, how does requestAnimationFrame fits in this picture? I know that it tells the browser that it wishes to perform a re-paint. Or... is position fixed simply the way to go? I'm interested in this topic because I'm working on a plugin for sticky elements.

Any info or advice is appreciated!

Upvotes: 3

Views: 1575

Answers (1)

JasonK
JasonK

Reputation: 5294

Since scroll events can fire at a high rate, the event handler shouldn't execute computationally expensive operations such as DOM modifications. Instead, it is recommended to throttle the event using requestAnimationFrame, setTimeout or customEvent.

It’s important to not only use requestAnimationFrame for your animations, but also to use it in the right way. - html5rocks

Also see https://developer.mozilla.org/en-US/docs/Web/Events/scroll

This is a nice little piece of code to get the right browser prefix. If requestAnimationFrame is unsupported, we fall back to 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
});

Upvotes: 6

Related Questions