Front end performance optimization classic: javascript anti shake throttling

Hello, I'm Lanfeng in the front end, a program yuan in a second tier city. Today, I mainly share with you some performance optimization of the front end, js anti shake throttling, which is a common performance optimization scheme of the project and a common problem in the interview. I hope the following articles are helpful to you.

We will use some methods during the project, such as anti shake, throttling, de duplication, deep copy and shallow copy, array flattening, disorder, curry and other classic methods.
When we are developing, there are many scenarios that frequently trigger events, such as real-time request from search box, onmousemove,onscroll oninput resize onkeyup keydown, etc. we need to optimize these high-frequency events and reduce the frequency of code execution
Optimize high-frequency events onscroll oninput resize onkeyup keydonw... Reduce the frequency of code execution. At this time, function anti shake and function throttling are needed.
The two common libraries are underscore and lodash. This javascript has anti shake and throttling functions. For more information, please refer to the following document address.
underscore document address: https://underscorejs.net/#throttle
lodash document address: https://www.lodashjs.com/docs/lodash.throttle
Process of web page display:

  • javascript animation / adding some DOM elements to the page
  • Style determines what style rules should be used for each DOM
  • Layout layout to calculate the position and size of the final display
  • Paint DOM, painting at different levels
  • Composite render layer merge

The user's scroll and resize behavior will cause the page to re render continuously. If a large number of operations are performed in the bound callback function, the dom will also have page jams
Optimization scheme:

1, Function Throttle

Throttling is to ensure that the core code is executed only once in a period of time

For example: water droplets accumulate to a certain weight before they fall

1. Simple throttling function

//We can click quickly. I can configure one click within 1s
<button>Quick click</button>
 function throttle(func, wait){
    let  previous = 0; //Last default
    return function(){
        let now = Date.now()
        if(now - previous> wait){
            func.apply(this, arguments);
            previous = now
        }
    }
}

function logger(e){
	console.log('log -----')
}
btn.addEventListener('click',throttle(logger, 1000))function throttle(method, dalay){

2. Full version:

function throttle(func, wait,options){
    // trailing should be triggered last time (default trigger)
    //leading deferred execution
    let args, context, previous = 0,timeout = null;
    let later = function(){
        previous = options.leading === false ? 0 : Date.now();
        func.apply(context, args)
    }
    let throttled = function (){
        args = arguments;
        context = this;
        let now = Date.now(); //present time

        if(!previous && options.leading === false){
            previous = now
        }
        let remaning = wait - (now-previous);

        if(remaning <= 0) { //for the first time
            if(timeout){}
            clearTimeout(timeout)
            timeout = null
           func.apply(this, args) 
           previous = now
        } else if(!timeout && options.trailing !== false) {
            timeout = setTimeout(later, remaning)
        }
    }
    return throttled
}
  function logger(){
      console.log('logger')
  }
  btn.addEventListener('click',throttle(logger, 1000,{trailing: true, leading: false}))

Principle: if the event is triggered continuously, the event is executed only once every other period of time

3. Application scenarios

  1. Implementation of DOM element drag function
  2. Calculate mouse movement distance
  3. Listen for scroll events

2, Debounce

Anti shake means that an event can only be triggered after a period of time. If an event is triggered again after a period of time, the time will be recalculated

For example: you are in an elevator, the door is about to close, and suddenly someone is ready to come up. The elevator did not change the floor, but opened the elevator door again. The elevator delayed the function of changing the floor, but optimized the resources.

1. Introduce the underscor library to experience debounce

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Anti shake</title>
    <style>
        #container{
            width: 200px;
            height: 100px;
            border: 1px solid red;
            text-align: center;
            line-height: 100px;
        }
    </style>
</head>
<body>
    <!--Anti shake-->
    <div id="container"></div>
    <script src="https://unpkg.com/underscore@1.13.1/underscore-umd-min.js"></script>
    <script>
       
       let  btn = document.getElementById('#container');
       let count = 0;
       function doSomeThing(){
           // Callbacks or Ajax requests may be made
            container.innerHTML = count++;
          
       }
     // High order function anti chattering
     container.onmousemove = _.debounce(doSomeThing, 300);
     // Anti shake:
     //The event response function (doSomeThing) is executed after a period of time. If it is called again within this period of time, the execution time will be recalculated; When the function is not called again within a predetermined time, the response doSomeThing function is executed
    </script>
</body>
</html>

Note: the event response function (doSomeThing) is executed after a period of time. If it is called again within this period of time, the execution time will be recalculated; When the function is not called again within a predetermined time, the response doSomeThing function is executed

2. Simple anti shake function

function debounce(func, wait, immediate){
      let timeout
      return function(){
          clearTimeout(timeout);
          if(immediate){
              let callNow = !timeout
              if(callNow){
                func.apply(this,arguments)
              }
          }
          timeout = setTimeout(()=>{
              func.apply(this,arguments)
              timeout = null
          }, wait)
      }
  } 

function logger(e){
	console.log('log -----')
}
btn.addEventListener('click',debounce(logger, 1000, true))

3. Full version:

 /**
   * Anti shake function
   * 
   * @param {*} func Function to call
   * @param {*} wait  delay time 
   * @param {*} immdeidate  Execute now
   * @returns 
   * by Front end Lanfeng
   */
  function debounce(func, wait, immdeidate){
    var timeout, result;
   
    var debounced = function(){
        //Change the direction of this inside the execution function
        var context = this;
        var args = arguments
        if(timeout) {
            clearTimeout(timeout)
        }

        if(immdeidate){   
          let callNow = !timeout;
          timeout = setTimeout(()=>{
              timeout = null;
          }, wait);

          //Execute now
          if(callNow) {
            result =  func.apply(context,args)
          }
        
        } else {
         timeout = setTimeout(function(){
             func.apply(context,args)
         }, wait);
         }
         return result
        
    };
    debounced.cancel = function(){
        clearTimeout(timeout)
        timeout = null
    }
  
    return debounced;
}

4. Application scenarios

  1. Scroll event scroll
  2. Zoom resize event for browser window
  3. When entering a query in the search box
  4. Form Validation
  5. Submit event for button

Pay attention to the official account number: programmer Shi Lei, reply: 001, you can get the source code.

Tags: Javascript Front-end Optimize

Posted on Wed, 03 Nov 2021 22:13:58 -0400 by mark s