Website development advanced anti shake throttling

Posted by Joseph Witchard on Fri, 21 Jan 2022 16:22:31 +0100

1, Foreword - why anti chattering or throttling

The realization of anti chattering or throttling is mainly based on the following purposes:

  • Reduce server pressure when querying in time.
  • Frequently perform DOM operations, resource loading and other heavy behaviors, resulting in UI pause and even browser crash.
  • The requirement is to perform subsequent processing at a certain frequency.

2, Debounce

The so-called anti shake is to combine the events that trigger very frequently into one to execute, so as not to mistake one event for many times. That is, the callback function is executed only once within the specified time. If the event is triggered within the specified time, the execution time of the callback function will be calculated again based on the moment. Knocking the keyboard is an anti shake operation that you will touch every day.

To understand a concept, you must first understand the scenario in which the concept is applied. What are the anti shake scenarios in the JS world?

  • Log in, send SMS and other buttons to prevent users from clicking too fast, so as to send multiple requests and need anti shake;
  • When the browser window size is adjusted, the resize times are too frequent, resulting in too many calculations. At this time, it needs to be in place at one time, so anti shake is used;
  • Submit forms;
  • Save the text editor in real time, and save it after one second without any change operation;
  • input event (of course, throttling can also be used to realize real-time keyword search);

Implementation principle:

  • Once triggered, the previous timer will be cleared and a new timer will be registered. The callback function is not executed until the wait time is stopped.

  • If the event is triggered continuously, the process will be repeated to prevent the target function from being called too frequently.

The logic code is as follows. You can see that "anti shake is to reset clearTimeout(timer)"

function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }

3, Throttle

Throttling, as the name suggests, controls the flow of water. Control the frequency of events, such as once in 1s or even once in 1 minute. It is similar to the rate limit controlled by the server and gateway.

  • scroll event, calculating location information every second;
  • The browser plays events and calculates progress information every second;
  • The input box searches and sends the request in real time, displays the drop-down list, and sends the request every second (anti shake can also be realized);

Implementation principle:

  • As long as triggered, the timer will be registered only when the current timer is empty.

  • If events are triggered continuously, they will only be triggered at fixed event intervals.

There are two ways to achieve throttling: setTimeout and timestamp.

setTimeout

function throttle(func, wait) {
  let timeout;
  return function () {
    if (!timeout) {
      timeout = window.setTimeout(function () {
        func.apply(this, arguments);
        timeout = null;
      }, wait);
    }
  };
}

time stamp

function throttleTime(func, wait) {
  let prev = 0;
  return function () {
    let now = Date.now();
    if (now - prev > wait) {
      func.apply(this);
      prev = now;
    }
  };
}

From the above logic code, we can see that "throttling focuses on switch lock timer=null"

4, Summary

  • Anti shake: to prevent shaking, the event trigger will be reset in unit time to avoid multiple false triggering of events.

  • Throttling: control the flow. Events can only be triggered once per unit time. If the flow limit on the server side is Rate Limit.

5, Sample code

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="bt1">Anti shake</button>
    <button id="bt2">throttle</button>
  </body>
  <script>
    // Anti shake
    function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }
    // throttle
    function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
    function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }
    let bt1 = document.getElementById("bt1");
    let bt2 = document.getElementById("bt2");
    bt1.onclick = debounce(function () {
      console.log(1);
    }, 1000);
    bt2.onclick = throttleTime(function () {
      console.log(2);
    }, 1000);
  </script>
</html>

Topics: Front-end Optimize