Reputation: 252
I was reading an article on HTML5Rocks that gave an example about scrolling through a webpage and checking an array of DOM elements offsetTop's to see if they should be visible.
The article says the best practice way of doing this would be to update a variable with the windows current offset top every time a scroll event is fired. When the first scroll event is fired, it triggers the requestAnimationFrame process of checking offsetTop's of the DOM elements. This decouples the visibility logic from the scroll event.
While I understand the benefit of certainly decoupling these two processes (since the scroll event could be called hundreds of times a second), I can't see the benefit of running the visibility logic every 16ms after the first scroll event, regardless of whether the user has continued to move or not..
Can someone please explain what part of the process I'm missing here?
Upvotes: 4
Views: 1595
Reputation: 664185
I think it's well explained in the article.
What else can we do? Well for one thing we are constantly running requestAnimationFrame and that’s not necessary if we haven’t just scrolled since nothing will have changed. To fix that we have the onScroll initiate the requestAnimationFrame
Now whenever we scroll we will try and call requestAnimationFrame, but if one is already requested we don’t initiate another. This is an important optimization, since the browser will stack all the repeated rAF requests and we would be back to a situation with more calls to update than we need.
Thanks to this setup we no longer need to call requestAnimationFrame at the top of update because we know it will only be requested when one or more scroll events has taken place. We also no longer need the kick off call at the bottom, either, so let’s update accordingly:
var latestKnownScrollY = 0,
ticking = false;
function onScroll() {
latestKnownScrollY = window.scrollY;
if (!ticking) {
requestAnimationFrame(update);
}
ticking = true;
}
function update() {
ticking = false; // reset the tick so we can capture the next onScroll
var currentScrollY = latestKnownScrollY;
// Do visibilty logic and animation here
}
So, "regardless of whether the user has continued to move or not" is not really true. update
is only called during (or a littlebit after) the scroll, and at a browser-choosen frame rate instead of a rate of hundreds of events per seconds.
Upvotes: 3