Front-end performance optimization | Anti-shake and throttling

1. Foreword

Why do we need to optimize performance? How important is performance optimization? Excellent performance is to provide a better user experience, speed up website loading, improve search engine ranking, save Server resources, Adapt to various devices and network environments, etc. By continuously optimizing performance, user satisfaction can be improved, website traffic can be increased, and business results can be improved.

At the same time, Performance optimization is a double-edged sword, with good and bad sides. The good side is that it can improve website performance, but the bad side is that there are many configurations, complex code, or too many rules to follow. And some performance optimization rules do not apply to all scenarios, so performance optimization is not a blind pursuit, but needs to be used with caution.

Antishaking and throttling are two commonly used performance optimization methods in JavaScript. We also encounter this frequently during interviews. Their role is to reduce the number of executions of functions to improve the performance of the code. This article will introduce in detail the definition, principle and implementation method of Antishake and Throttle, and discuss how to use them in specific functions.

2. Understanding of anti-shake and throttling

What is Debounce

As shown in the figure below, debounce (Debounce) means to execute the callback function function after the event is triggered delay time. If set here If the event is triggered again within the delay time, the time will be restarted. This can be used on some click request events to avoid sending multiple requests to the backend due to multiple user clicks.

What is Throttle

As shown in the figure below, throttling (Throttle) refers to specifying a unit time (delay delay time). Within this unit time, there can only be one callback that triggers the event. Function execution, if an event is triggered multiple times in the same unit of time, only one event will take effect. Throttling can be used in the event listening of the scroll function to reduce the frequency of event calls through event throttling.

3. Application scenarios of anti-shake function

  1. Search box real-time search: When users type in the search box, they often want to search in real time. Using the anti-shake function can delay the sending of the search request, and only send the request after the user stops typing for a period of time to avoid frequent request operations.

  2. Form input validation: During the form input process, each user input may trigger a validation operation. The anti-shake function can be used to delay triggering the verification operation and only perform verification after a period of time after the user input is completed to avoid frequent verification operations.

  3. Browser window resize event: When the user resizes the browser window, the resize event is triggered. Using the anti-shake function can delay the triggering of the resize event, and only perform the corresponding operation after the user stops adjusting the window for a period of time, thus avoiding frequent calculation and layout operations.

  4. Mouse movement event: In some specific interaction scenarios, corresponding interactions need to be made based on the movement position of the mouse. Using the anti-shake function can delay the triggering of the mouse movement event and only perform the corresponding operation after the user stops moving the mouse for a period of time to avoid excessively frequent operations.

Taking the user search box real-time search request backend as an example, let’s take a closer look:

Original code, without anti-shake optimization

<div class="box">
  Input events are not anti-shake processed: <input type="text" id="demo" name="demo">
</div>
<script>
  
  function req(value){
    console.warn("request: " + value + ", time: " + new Date());
  }

  const inputBox = document.getElementById("demo");
  inputBox.addEventListener("keyup",e=>{
    req(e.target.value);
  })
</script>

As shown in the above results, as long as we enter text in the input box, a simulation request will be triggered, which is a bad experience and a waste of resources for users and developers.

Thinking: We thought that each time the user inputs text, it takes a certain amount of time, so we can define a complete input within the specified time before making a request, so that we can reduce the pressure on the background.

After optimization using anti-shake function

Anti-shake rules: Entering text and pressing the keyboard within 500ms will not trigger the request event. Instead, the request will be sent after the timer of the input box 500ms stops input.

Optimization: Let’s modify the above code, monitor our input box, input continuously within 500ms, do not perform any operations, and send after 500ms One request.

<div class="box">
  Input events for anti-shake processing: <input type="text" id="demo" name="demo">
</div>
<script>
  
  function req(value){
    console.warn("request: " + value + ", time: " + new Date());
  }

  const inputBox = document.getElementById("demo");
  inputBox.addEventListener("keyup",e=>{
    debounce(() => req(e.target.value), 500);
  })
</script>

As can be seen from the above running results, continuous input of text in the input box within 500ms will not trigger the request event, but the input will stop after the timer of the input box 500ms Then send the request.

The implementation principle is very simple, that is, add a timer to count frequently input input box request events. Frequent input within the specified time will not make a request, but the function will be executed only when the input stops within the specified time interval.

When the input is stopped but within this timer count time, the trigger request event will be retried.

4. Application scenarios of throttling function

  1. Page scroll event: When the user scrolls the page, scroll events will be triggered frequently. Using the throttling function can control the triggering frequency of scroll events, avoid excessive calculation and rendering operations, and improve the performance and smoothness of the page.

  2. Window resize: When the user resizes the browser window, the resize event will be triggered continuously. Use the throttling function to limit the firing frequency of the resize event to avoid excessive calculation and layout operations.

  3. Click the button frequently: In some scenarios, clicking the button may trigger repeated submission operations. Use the throttling function to limit the triggering frequency of button clicks and prevent repeated submissions.

  4. Animation Scene: Avoid performance problems caused by triggering animation multiple times in a short period of time

  5. Drag-and-drop scenario: In some scenarios, frequent triggering of position changes will cause performance problems. It is only executed once within a fixed period of time to prevent extremely frequent triggering of position changes.

Taking frequent clicks on buttons to prevent repeated submissions as an example, let’s take a closer look:

Original code, not optimized for throttling

<button id="demo" style="margin: 50px;">Click the button</button></button>
<script>
    let value = 1
    
    function req(){
        console.warn("request: " + value + + + ", time: " + new Date());
    }
    const ele = document.getElementById("demo");
    ele.addEventListener("click", (e) => {
        req()
    });
</script>

As shown in the above results, as long as we click the button, a simulation request will be triggered. In addition to the pressure on the server, this will also cause multiple data submissions, which may cause the risk of data duplication.

After optimization using throttling function

Throttling rule: If you click the button frequently within 1000ms, you can only succeed once.

Optimization: When the button is clicked frequently and multiple times, in order to avoid multiple requests from the user, throttling restrictions are implemented. Within a specified 1000ms time, only one click can be successful. Trigger action.

<button id="demo" style="margin: 50px;">Click the button</button></button>
<script>
    let value = 1
    
    function req(){
        console.warn("request: " + value + + + ", time: " + new Date());
    }
    const ele = document.getElementById("demo");
    ele.addEventListener("click", (e) => {
        throttle(() => req(), 1000)
    });
</script>

It can be seen from the above running results that after clicking the button multiple times within 1000ms, only one success occurred.

5. Implement anti-shake function and throttling function

Implement anti-shake function

Implementation ideas

  1. Define a timer variable, which defaults to null.

  2. When the event fires, clear the previous timer.

  3. Create a new timer to delay execution of the target function.

  4. During this time, if the event is triggered again, repeat steps 2 and 3.

  5. When the event is not triggered again within the delay time, the target function is executed.

 * @desc anti-shake function: within a certain period of time, only the last operation is performed, and the function is executed after wait milliseconds.
 * @param {Function} func function
 * @param {Number} wait The number of milliseconds to delay execution
 * @param {Boolean} immediate true means immediate execution, false means non-immediate execution
 */
let timeout

function debounce(func, wait = 500, immediate = false) {
  
  if (timeout) clearTimeout(timeout)
  
  if (immediate) {
    let callNow = !timeout
    timeout = setTimeout(() => {
      timeout = null
    }, wait)
    if (callNow) typeof func === 'function' & amp; & amp; func()
  } else {
    
    timeout = setTimeout(() => {
      typeof func === 'function' & amp; & amp; func()
    }, wait)
  }
}


Implement throttling function

Implementation ideas

  1. Define a flag variable to indicate whether execution of the target function is allowed, the default is 0.

  2. When the event is triggered, the difference between the current timestamp and the mark variable is checked. If the difference is greater than the set delay time, the function is executed and the mark variable is set to the current timestamp. If the difference is less than the set delay time, it will not be executed.

  3. When the event is triggered again within the specified time interval, repeat steps 2.

 * @desc throttling function: can only be triggered once within a certain period of time
 * @param {Function} func function
 * @param {Number} wait The number of milliseconds to delay execution
 */
let previous = 0
function throttle(func, wait = 500) {
  let now = Date.now()
  if (now - previous > wait) {
    typeof func === 'function' & amp; & amp; func()
    previous=now
  }
}



Summary

In this article, we learned about anti-shake and throttling optimization techniques in JavaScript. Both technologies are designed to solve performance problems caused by frequently triggered events and improve page performance and user experience by limiting the frequency of event triggers.

We first introduced the definition and difference between anti-shake and throttling. Anti-shake refers to executing only the last triggered event within a period of time, while throttling refers to triggering events at fixed intervals within a period of time. Then, we elaborate on the principles and implementation of anti-shake and throttling.

In practical applications, we often encounter scenarios where we need to use anti-shake and throttling to optimize user interaction, scrolling events, input box input, etc. By properly anti-shaking and throttling, we can reduce redundant calculations and rendering and improve page fluency and response speed.

At the end of the article, some common optimization libraries and tools are provided to facilitate developers to quickly apply them in actual development.

Through studying this article, I hope that everyone can fully understand the principles of anti-shake and throttling, and can reasonably apply them to their own projects based on actual conditions to improve page performance and user experience.