Events like 'click', 'scroll', 'drag' etc. can be abused to trigger the event handler function as many times as to noticeably degrade the performance of a web app. To limit such unwanted function calls in order to keep the performance up to the mark, we use polyfills like Throttling and Debouncing.
Let us try to understand both of these function timing algorithms but first by some analogy that makes it easy to digest.
Your grandmother promises you an ice-cream when you ask her for one but after every 2 days, not any early than that. You asked for an ice-cream today, you got it already.
Throttling
Now, a day later, you ask your grandmother for another ice-cream. She tells you, you can have one tomorrow or anytime after that but not today since it's not 2 days from the last time yet. So the rule is simple, you get an ice-cream every 2 days. That's throttling your call to the function askForIcecream(). All your early requests were simply ignored. Technically, when you throttle a function, you make sure once it is called it cannot be called again until a given time interval has passed.
Debouncing
What if your grandmother was a little more grumpy? You just had your ice-cream yesterday and ask her for another one today, she sends you away and tells you not to ask for it for another 2 days now. You broke the rule, you get a punishment. Making an untimely call for an ice-cream just got it delayed by another 2 days. You keep making early requests and your ice-cream keeps getting delayed. That's debouncing your call to the function askForIcecream(). All your early requests were penalized. Technically, when you debounce a function, you make sure its called only after a given interval of time has passed from the last call but there's an additional criteria. Every time someone tries to invoke the function before its time, the "delay" gets added.
Shall we check our understanding against the real deal now? How do we apply this to our web apps? I mentioned a few events in the beginning. A few examples involving those events shall be sufficient case-study to start using Throttling and Debouncing in our next project.
Case Study
1 - Search-box -
There's a web-app that lists a variety of products from different categories on its products page. What's the best way to display only the relevant products out of a million other products available? Yeah, give the user a search box. A search box with a button that says "Search" or "Go". You input the name of the product, click on the button and a function (called getResults) fires that gives you the relevant list of products matching your search string. I do not see a reason to restrict number of times getResults() is called. Let's think about another scenario, your users also want suggestions as a list in a drop-down selection panel. As soon as they start typing they want to see the suggestions appear that of course should keep changing as they keep typing (You know even Google has this on its search page). Now when you think, you'll figure out, you need to use some "type" event. So what options do we have in JavaScript? We have "onKeyPress", "onKeyUp" and "onKeyDown". Let's say we want to use "onKeyPress" and fire a function (getSuggestions) every time the user types a character in the search-box. Now when you think again, this can keep firing getSuggestions() on every character that may not be very useful. Why not fire a function when the user types and then stops for a while (say 2 milliseconds). Technically speaking, we now want to debounce the call to getSuggestions() for 2 ms.
2 - Resizing the window -
Lets say you want to display different content when an user resizes the window to a smaller size. You can obviously do that with some CSS and media queries but lets assume you want to detect the change in size of the window and you want to do it optimally. Normally when you attach an event listener function to the "resize" event on "window" object, the handler keeps firing as you drag the cursor, which may not be optimal for your use case. In such cases you'd want some expensive logic that is inside the event handler function to run after say, every 1 second. Technically in such cases you'd throttle the heavy function that is called from within the event handler function every 1 second. All the "resize" events shall be ignored until 1 second from the last call to the event handler.
There can be many similar examples and scenarios where you'd want to choose one of the above mentioned strategies to keep the performance intact. I leave that on you to explore. I hope this piece of information is sufficient to make things clear at least theoretically.
For a practical example of how to implement the debouncing poly-fill, check out the following pen
https://codepen.io/mayankav/pen/yLaXJKO
For a practical example of how to implement the throttling poly-fill, check out the following pen
https://codepen.io/mayankav/pen/ExWbLmv
Originally Posted Here -
https://mayankav.webflow.io/blog/throttling-vs-debouncing
Top comments (3)
Well explained 👍🏼
Thanks Rishikesh, that's my first blog :)
Great start, expecting more in future.