“This is the first day of my participation in the Gwen Challenge in November. Check out the details: The last Gwen Challenge in 2021”

Hello, everyone, I am Front-end LAN Feng, a program yuan in a second-tier city. Today, I mainly share with you some front-end performance optimization, JS anti-shaking throttling, which is a relatively common performance optimization scheme of the project, but also a common problem encountered in the interview. I hope the following article is helpful to you.

We will use some methods in the project process, such as anti-shake, throttling, weight removal, deep copy shallow copy, array flattening, out of order, Currification and other classical methods. During our normal development, there will be many scenarios that frequently trigger events, such as real-time search box sending requests, onMousemove, onScroll onInput Resize onKeyUp keyDown and so on. We need to optimize these high-frequency events to reduce the code execution frequency. Onscroll onInput resize onKeyUp keydonw… Reduce the frequency of code execution, which requires the use of function stabilization and function throttling. Two of the more common libraries are underscore and Lodash, which both have antioxidation-throttling functions in javascript. For more information, see the documentation address below. Underscore document address:underscorejs.net/#throttleLodash document address:www.lodashjs.com/docs/lodash…Webpage presentation process:

  • Javascript animation/Add some DOM elements to the page
  • Style determines what style rules should be used for each DOM
  • Calculates the position and size of the final display
  • Paint draws the DOM at a level of different rows
  • Composite render layer merge

The user’s scroll and resize behavior will cause the page to be constantly re-rendered. If the bound callback function manipulates the DOM a lot, the page will also be stuck:

Function Throttle

Throttling ensures that core code is executed only once over a period of time

For example: water drops accumulate to a certain weight before falling

1. Simple throttling function

// throttling let's quick click and I can configure clicks within 1s to count once<button> Quick click </button>function throttle(func, wait){
    let  previous = 0; // Last default value
    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){

Copy the code

2. The Full version:

function throttle(func, wait,options){
    // trailing should fire the last time (default)
    //leading Delays 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}))
Copy the code

Principle: If an event is continuously triggered, only one event is executed at a time interval

3. Application scenarios

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

Ii. Debounce

If the event is triggered again after the end of a period of time, the time will be recalculated

Here’s an example: You’re in an elevator, the door is about to close, and suddenly someone is about to come up. Instead of changing floors, the elevator opens the door again, delaying the function of changing floors but optimizing resources.

1. Introduce the Underscor library and experience debounce

<! DOCTYPEhtml>
<head>
    <meta charset="UTF-8">
    <title>Image stabilization</title>
    <style>
        #container{
            width: 200px;
            height: 100px;
            border: 1px solid red;
            text-align: center;
            line-height: 100px;
        }
    </style>
</head>
<body>
    <! -- if you -- -- >
    <div id="container"></div>
    <script src="https://unpkg.com/[email protected]/underscore-umd-min.js"></script>
    <script>
       
       let  btn = document.getElementById('#container');
       let count = 0;
       function doSomeThing(){
           // Callback or Ajax requests may be made
            container.innerHTML = count++;
          
       }
     // High order function buffeting
     container.onmousemove = _.debounce(doSomeThing, 300);
     / / if you:
     // 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 is recalculated; When the function is not called again within a predetermined period of time, the response doSomeThing function is executed
    </script>
</body>
</html>
Copy the code

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 is recalculated. When the function is not called again within a predetermined period of 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){
              letcallNow = ! timeoutif(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))
Copy the code

3. Full version:

 /** ** function **@param {*} Func Specifies the function to call@param {*} Wait Delay *@param {*} Whether the ImmdeIDATE will be executed immediately *@returns * by */
  function debounce(func, wait, immdeidate){
    var timeout, result;
   
    var debounced = function(){
        // Change the direction of this inside the executing function
        var context = this;
        var args = arguments
        if(timeout) {
            clearTimeout(timeout)
        }

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

          // Execute immediately
          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;
}
Copy the code

4. Application scenarios

  1. Scroll event
  2. Resize event for the browser window
  3. Search box when entering a query
  4. Form validation
  5. Button’s submit event

Concerned public number: programmer Shi Lei, reply: 001 can obtain the source code