1

What would be better solution performance-wise - executing a function every 100 ms via setInterval or executing a function when page is scrolled? I just checked and single scroll can cause a function to be executed over 50 times. Setting setInterval to 100ms would cause function to be executed only 10 times per second but on the downside the function would be executed even if the page is not scrolled.

The function is rather simple (checkes window.pageYOffset and changes style if it's over 100)

Vortic
  • 75
  • 1
  • 8

1 Answers1

3

This sounds like a job for a debounce function. Such a method rate limits calls to a function.

You mention the single scroll hitting your callback over 50 times. By utilizing debounce the callback would not be invoked until the debounce function IS NOT called for a specified amount of time. (in the below example 300ms)

var scrollHandler = debounce(function() {
    // your window.pageYOffset logic
}, 300);

window.addEventListener('scroll', scrollHandler);

A much more complete explanation and example debounce function can be found at:

https://davidwalsh.name/javascript-debounce-function

or

Can someone explain the "debounce" function in Javascript

Using such an approach will make a more optimized number of calls, and only when the page is interacted with (sounds like this should happen when the page is scrolled).

Community
  • 1
  • 1
roger
  • 1,091
  • 1
  • 7
  • 15
  • Sounds great but I'm getting "Uncaught ReferenceError: debounce is not defined" error. And I think you're missing one semicolon - after "300)" – Vortic Jan 05 '17 at 00:50
  • Check out that link, there is an example debounce function there you'll need to define / drop in to your project. (Nice catch, will fix that semicolon!) – roger Jan 05 '17 at 00:53
  • This method seems to lag sometimes but I managed to get it working smoothly by changing the value to 16. Full page scroll causes function to be executed 30 times (as opposed to 50 with only half page scrolled before) so this is already an improvement! But the question still remains. Which way is better for performance - window.onscroll / debounce or setInterval(100ms)? – Vortic Jan 05 '17 at 01:22
  • To elaborate - if the value is set above 16 then for some reason scrolling continously will only execute function 4-6 times during full page scroll. – Vortic Jan 05 '17 at 01:27
  • If you're continuously scrolling, the debounce should not fire until you stop scrolling (and the time specified has elapsed - 16ms is really low, so something in the range of 200+ should only fire once) – roger Jan 05 '17 at 01:41
  • The problem is I need that function to be executed pretty often when continously scrolling (but not too often, something like 10-15 calls per second would be perfect). What I don't understand is why setting 15-16ms causes function to be executed 30-60 times but anything above that (even 17ms) fires function only 2-5 times. – Vortic Jan 05 '17 at 01:51
  • https://jsfiddle.net/476rkj0n/ here's fiddle. It works good if it's set to 16ms but change it to anything above and you'll see small lags. – Vortic Jan 05 '17 at 02:02
  • @Vortic The frequency your function gets called by debounce would be 1000 / the number you pass in. If you want it to be about 15x / second, then set it to approximately 1000/15. 65 for example. – Jake Jan 05 '17 at 02:08
  • Ah I see what you are trying to do @Vortic - thanks for the fiddle. Makes more sense as to why you set the interval value so low (~16). Here's an article by css-tricks tackling a similar feature: https://css-tricks.com/scroll-fix-content/ unfortunately it looks like their solution is pretty similar (that little lag you're seeing might be tough to completely avoid using debounce) but this approach still beats the setInterval one - if your user scrolled quickly they might see a similar 'lag' and debounce cuts down on method executions by a fair margin from a straight up listener albeit the lag – roger Jan 05 '17 at 02:25