Debouncing vs Throttling

First, let me define what debouncing and throttling are in my own words before I begin:

Debouncing: Executing a function after a certain period of time if it was not called again.
Throttling: Executing a function at most once in a certain period of time.

There are different applications that debouncing and throttling can be considered for code optimization and thus better user experience. Today, I will discuss about mouse scrolling to demonstrate the difference between two.

let timesCalled = 0;
const onScroll = () => {
const currentY = document.documentElement.scrollTop;
const totalY = document.documentElement.scrollHeight - document.documentElement.clientHeight;
const HUNDRED_PERCENT = 100;
  console.log((currentY / totalY) * HUNDRED_PERCENT, timesCalled++);
};

The onScroll function in the code snippet above logs the percent of current scroll location (with 0 being the top and 100 being the bottom of the page) and the number of times the user scrolls up or down.

When we test the code out on a website, we can see that onScroll function is called around hundred times when scrolled all the way down using a laptop trackpad. Calling a CPU-intensive function too many times like this can significantly slow down the website, so we need to make sure avoid it like a plague.

To limit the number of times a function is called in a window of time, we can use throttling:

const throttle = (func, wait) => {
let called = false;
return () => {
if (!called) {
called = true;
setTimeout(function() {
func();
called = false;
}, wait);
}
};
};
document.addEventListener("scroll", throttle(onScroll, 50));

We can utilize Javascript’s closure to create a throttling function. Throttle function above takes in a function to be called and wait time as parameters. The function taken in as a parameter is invoked only after the wait time is over. Thus, the throttled function in the example can only be called once every 50 ms.

const debounce = (func, wait) => {
let timeout = null;
return () => {
clearTimeout(timeout);
timeout = setTimeout(function() {
func();
}, wait);
};
};

Debouncing, however, will reset the timer every time the function is called. Debounce function above still takes in same two parameters, function to be invoked and wait time, but will clear setTimeout function at every subsequent function call. So the function is called after the wait time, under the assumption that the user does not scroll again.