JavaScript Throttle and Debounce | Concept and Comparision

Throttling and debouncing are two popular and widely performed coding techniques that will help to improve the performance of JavaScript code that undergoes execution repeatedly within a certain period of time. In this tutorial, we’ll learn about the JavaScript Throttle and Debounce and how to implement them in our code to boost our code’s performance and write better and faster code in JavaScript.

Throttling and debouncing enable coders with control over the rate at which a method is called. They are especially useful when dealing with event handler assignments. We can take examples of scroll handlers, keyboard events, or even just clicking a button rapidly.

What is Throttle?

The throttle is a higher-order function that takes a method and a timeout function and only allows that function to be executed at most once per the amount of time specified. It is to ensure that the function is called at most once in a specified time period. This means throttling will stop a function from running if it has run just recently.

So, where do we use the Throttling technique?

  • We use throttling in button clicks to prevent spam click.
  • We can use throttling in an API call.
  • The throttle can be used in a mousemove/touchmove event handler.

Implementation of Throttle

First, let us take a simple example, which explains the code with and without the Throttle.

export class IncreaseTheNumber extends Component<{}, {num : number}> {
state = {num: 0}; 
increase = () => { 
 this.setState({num: this.state.num + 1});
}
render() { 
  return ( 
     <div> 
       {this.state.num}
      <div> 
        <button onClick={this.increase}>Increment!</button> 
      </div> 
     </div> 
   ); 
 }
}

In this example above, we have a state num and a method that can increase this state increase. There is a button we can click which increments num. Here, we can click the Increment button as quickly as we want and it will increment the num state. Now consider we need to delay state num to increase as quickly as we click on the button. So, we can use the throttle to slow down the increments. Check out the example below in which the throttle is implemented:

export class IncreaseTheNumber extends Component<{}, {num: number}>{
state = {num: 0}; 
increase= () => {
   this.setState({num: this.state.num + 1}); }
}
function throttle(func, timeout) {  
  let exexute: true;  
  return (...args) => {    
   if (!execute) {      
      return;    
   }     
    execute= false;    
    func(...args);    
    setTimeout(() => {      
       execute = true;    
     }, timeout);  
   };
}
increaseWithThrottle = throttle(this.increase, timeout);
render() { 
  return ( 
       <div > 
         {this.state.numSpells}
         <div> 
           <button onClick={this.increase}>Increment</button>          
           <button onClick={this.increaseWithThrottle}> Increment with Throttled </button> 
         </div> 
        </div> 
         ); 
 }
}

Here, We now have a button called increaseWithThrottlewhich implements the throttling technique and delays the increment of the num state.

Now, we need to understand the throttle method. The throttle is a method that takes a function and a timeout. Throttle returns a new method that forms a closure around the original one.

Here, we need to keep track of a variable called execute that prevents the inner method from executing unless the timeout has elapsed. If we execute the method we also fire a timeout that will set execute to true when the timeout has elapsed. This is pretty much how we implement the Throttling in JavaScript.

Now, let’s move on Debounce!!

What is Debounce?

Basically, Debouncing is likely used more than Throttling. In many cases, you can have a better impact with debouncing than a Throttle.

Debounce is just a bit different from the Throttle. In case of a throttle, we slow down method calls as they happen. But in case of debounce, we don’t execute the method at all until the previous execution of that method has stopped. This seems like a more secure way from the coding concept.

It is really useful if we want to perform a computation or fetch an API when the user is done typing, scrolling or navigating.

So, where do we use the Debounce technique?

  • We use debounce in a resize event handler.
  • We can use debounce in a scroll event handler.
  • Denounce can be used in auto-complete or auto-save features.

Implementation of Debounce

export class IncreaseTheNumber extends Component<{}, {num: number}>{
state = {num: 0}; 
increase= () => {
   this.setState({num: this.state.num + 1}); }
}
function debounce(func: Function, timeout: number) {  
   let timer: NodeJS.Timeout;  
   return (...args: any) => {    
      clearTimeout(timer);    
      timer = setTimeout(() => {      
          func(...args);    
        }
       ,timeout);  
      };
    }
incrementWithDebounced = debounce(this.increase, timeout);
render() { 
  return ( 
       <div > 
         {this.state.numSpells}
         <div> 
           <button onClick={this.increase}>Increment</button>          
           <button onClick={this.incrementWithDebounced}> Increment with Debounce</button> 
         </div> 
        </div> 
         ); 
   }
}

Using debounce function here, we’ll notice that we can click Increment with Debounce as many times as we like, but it will only execute after we’ve stopped clicking it. The code for this is similar to the previous Throttle component but only with debounce method.

Here, while the throttle relied on a simple true or false, with debounce, we need to maintain access to the timer. We implement the timer from the Node module because we need to clear the previous timeout every time the method gets called again. We then set a new timeout method to call the inner method.

So, this is how the Debounce is implemented.

Hence, the overall concept of JavaScript Throttle and Debounce is completely covered in this article.




0 comments