16

Can someone explaine and help me with this. My webpage is slugish because the scroll function is dragging it down. I need to add a delay but don't understand how to do this.

$(window).scroll(handleScroll);
Daniel Haro
  • 341
  • 1
  • 2
  • 11

2 Answers2

44

You could write a simple throttle debounce function to limit the times per second the scroll event will be handled.

function debounce(method, delay) {
    clearTimeout(method._tId);
    method._tId= setTimeout(function(){
        method();
    }, delay);
}

$(window).scroll(function() {
    debounce(handleScroll, 100);
});

This will make sure there's at least 100ms between each call to handleScroll (or, in other words, it's called at most 10 times per second).


As zzzzBov pointed out, what Zakas describes as a throttle function is actually a debounce function. The difference is that debounce discards the superfluous scroll events, while a throttle function should queue them up to be handled later (but at a given maximum rate).

In the case of scroll events, you don't want real throttling.

  • 8
    That's actually [debouncing](http://davidwalsh.name/function-debounce), which is slightly different from throttling. – zzzzBov Feb 25 '14 at 18:27
  • How can I use parameters in the function? For example I need something like debounce(handleScroll(parameter_1,parameter_2), 100) – Garavani Feb 10 '22 at 05:54
  • 1
    @Garavani: you could wrap it in an inline function: `debounce(function () { handleScroll(parameter_1, parameter2) }, 100)`. – Peter-Paul van Gemerden Mar 11 '22 at 21:50
  • I believe debounce vs. throttle depends on the feature you want to implement on scroll. See https://stackoverflow.com/a/65078485/5282202 – Oleksandr Pyrozhok Oct 24 '22 at 12:15
7

For scroll, you most likely need a throttle function like in Lodash or Underscore; great example:

function throttle(func, timeFrame) {
  let lastTime = 0;
  return function () {
      const now = new Date();
      if (now - lastTime >= timeFrame) {
          func();
          lastTime = now;
      }
  };
}

This is a simple implementation from this repo

It depends on what you implement by scrolling callback. In some cases, the throttle will be much better to use. For example, infinite scrolling.

So debounce only would trigger only when the user stops scrolling and we need to start fetching the content before the user reaches the bottom.

But with throttle, we can warranty that we are constantly checking how far we are from the bottom.

Conclusion:

  • debounce: Grouping a sudden burst of events (like keystrokes) into a single one.
  • throttle: Guaranteeing a constant flow of executions every X milliseconds. Like checking every 200ms of your scroll position to trigger a CSS animation.
  • requestAnimationFrame: a throttle alternative. When your function recalculates and renders elements on the screen and you want to guarantee smooth changes or animations. Note: no IE9 support.