Advance Javascript: Throttling


In my previous article I went through a performance optimization strategy called debouncing, in this article let’s go through an effective technique to manage the frequency of function execution – throttling. We’ll explore what throttling is, why it’s useful, and how to implement it with examples from both a console application and a web application using TypeScript.

What is Throttling?

Throttling is a technique used to ensure that a function is executed at most once in a specified period. This is particularly useful in scenarios where an event fires multiple times in quick succession, like keystrokes, window resizing, or scroll events. By throttling, we can control the execution frequency of a function, improving performance and user experience.

Why Use Throttling?

Imagine a scenario where you have a function that updates the UI based on user scroll events. Without throttling, the function could be called numerous times per second, potentially degrading performance. Throttling ensures that the function is called at most once every specified period, reducing the workload and improving efficiency.

Throttling in a Console Application

Let’s start with a simple example in a console application using Node.js. We’ll create a throttled function that logs a message only once every 2 seconds while the user types.

TypeScript Example:

import readline from 'readline';

type Throttle = <T extends(...args:any[]) => void> (func:T, limit: number) => (...args: Parameters<T>) => void;

const throttle : Throttle = (func, limit) => {
    let lastFunc: NodeJS.Timeout | undefined;
    let lastRan: number;

    return function (this: unknown, ...args: Parameters<typeof func>){
        const context = this;
        if(!lastRan) {
            func.apply(context, args);
            lastRan = Date.now();
        } else {
            if(lastFunc) clearTimeout(lastFunc);
            lastFunc = setTimeout(() => {
             if((Date.now() - lastRan >= limit)){
                func.apply(context, args);
                lastRan = Date.now();
             }
            }, limit);
        }
    };
}

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

const handleKeystroke = throttle((input: string) => {
    console.log('Keystroke is :', input.trim())
}, 2000);

console.log(' Start Typing :');
rl.on('line', handleKeystroke)

In this example, the handleKeystroke function logs the input at most once every 2 seconds, regardless of how fast you type and press Enter.

Throttling in a Web Application

Now, let’s look at an example in a web application. We’ll throttle a function that handles input events on a search field, ensuring the search function is only called at most once every 300 milliseconds.

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Throttling Example</title>
</head>
<body>
  <input type="text" id="searchInput" placeholder="Type to search..." />
  <script src="app.js"></script>
</body>
</html>

TypeScript (app.ts):

First, install TypeScript and configure it if you haven’t already

npm install typescript --save-dev
npx tsc --init

Now, here’s the TypeScript code for the web application

const throttle = <T extends (...args: any[]) => void>(func: T, limit: number) => {
  let lastFunc: ReturnType<typeof setTimeout>;
  let lastRan: number | undefined;
  return function (this: unknown, ...args: Parameters<T>) {
    const context = this;
    if (!lastRan) {
      func.apply(context, args);
      lastRan = Date.now();
    } else {
      if (lastFunc) clearTimeout(lastFunc);
      lastFunc = setTimeout(() => {
        if ((Date.now() - lastRan!) >= limit) {
          func.apply(context, args);
          lastRan = Date.now();
        }
      }, limit - (Date.now() - lastRan!));
    }
  };
};

const handleInput = throttle((event: Event) => {
  const target = event.target as HTMLInputElement;
  console.log('Search query:', target.value);
}, 300);

const searchInput = document.getElementById('searchInput') as HTMLInputElement;
searchInput.addEventListener('input', handleInput);

Explanation

  • Type Declaration
    • Throttle‘: A type for the throttle function which ensures the input function func is only called once every limit milliseconds.
  • Throttle Function
    • throttle‘ takes a function func and a limit limit in milliseconds.
    • Uses ‘lastFunc‘ to store the timeout ID and ‘lastRan‘ to store the timestamp of the last execution.
    • Checks if ‘lastRan‘ is undefined (first run) and executes ‘func‘.
    • If not the first run, clears any previous timeout and sets a new timeout to execute func after the remaining time until ‘limit‘ has passed
  • HTML and TypeScript Integration
    • The input field in the HTML triggers the throttled ‘handleInput‘ function
    • The ‘handleInput‘ function logs the search query at most once every 300 milliseconds

Conclusion

Throttling is a powerful technique to control the execution frequency of functions in JavaScript, ensuring they are called at most once in a specified period. By applying throttling in both console and web applications, you can significantly improve performance and user experience. Whether you’re managing user input, scroll events, or resize events, throttling ensures that your functions are executed efficiently and only when necessary.

For complete source – https://github.com/IndikaMaligaspe/advance-javascrips/tree/master/topics/performance-optimization

,

Leave a Reply

Your email address will not be published. Required fields are marked *