20190726 - Front-end Notebook - Anti-jitter and Throttle

Keywords: Javascript network

Anti shake

In order to avoid some monitoring events in their own anticipation of the situation, frequent triggering. or triggers events frequently on certain listening commands, such as resize, mousemove, etc.

Unshaken examples

       var count = 0,
          Elem = doc.getElementById('con')

        function appendCount(e) {
            console.log(e);
            
          Elem.innerHTML = count++
        }

        // Direct monitoring of execution without shaking
        Elem.addEventListener('mousemove', function() {
          appendCount()
        })

This leads to changes in Eelm.innerHTML as long as the mouse moves. Now it looks like it's okay. What if it's a lot of data rendering or requesting thousands of list data?

This will cause the browser to continue to reflow and redraw.

How to prevent tremor?

AppndCount () can only be executed within 1 s of the triggering time of mousemove unless the mousemove method is triggered.

var count = 0,
    Elem = doc.getElementById('con');
     
function debounce(fn, waitTime){
    // Define timer
     var timeoutFn = null;
     
     return function (){
          // Cleaning timer
          clearTimeout(timeoutFn);
          // Reset Timer
          timeoutFn = (() => {
              fn.apply(this, arguments)
          },waitTime)
     }
}

function appendCount(){
    ELem.innerHTML=count++;
}

Elem.addEventListener('mousemove', debounce(appendCount, 500))

Anti-shaking process

  • mousemove triggers debounce()`
  • Define a timer timeout Fn, return the execution content: clear the current timeout Fn timer (timeout Fn = null;), define the execution content.

    // debounce() returns content
    function (){
          // Cleaning timer
          clearTimeout(timeoutFn);
          // Reset Timer
          timeoutFn = (() => {
              fn.apply(this, arguments)
          },waitTime)
     }
  • When mousemove triggers again, the timeout Fn timer clears again, redefining the execution content
  • Only when the last mousemove, the timer is not cleared by debounce(), and the timeout Fn timer is finally executed by fn.apply(this, agruments);

throttle

This is how I understand throttling as opposed to shake-proof: when we want to trigger events that occur only once over a period of time, we can save more resources and network requests.

As an example of AppendCount() above, I just want to trigger an event AppendCount() within 3 seconds.

So what should we do?

var count = 0,
    Elem = doc.getElementById('con');

function throttle(fn,waitTime){
    var timeoutFn = null;
     
    return function () {
        // If a timeout Fn timer exists, wait for timeout Fn to complete
        if(!timeoutFn){
            timeoutFn = (() => {
                // Vacuum timer
                clearTimeout(timeoutFn)
                fn.apply(this, arguments)
            },waitTime)
        }     
    }
}

function appendCount(){
    ELem.innerHTML=count++;
}

Elem.addEventListener('mousemove', throttle(appendCount, 3000))

This is different from shake-proof. After waiting for timeout Fn to be executed, it is emptied by clearTimeout (timeout Fn), so that timeout Fn can be executed again after 3 seconds.

There's another way to write it, which is a little different from the above one. The above one is when throttle is triggered in 1s, but appendCount can only be executed in 4s. But here's the immediate execution. When the first s triggers throttle, appendCount is executed, and then throttle can be repeated after the fourth s.

var count = 0,
    Elem = doc.getElementById('con');

function throttle(fn, waitTime){
    // Define timer, execution state
    var timeoutFn = null,
        isRuning = false;
     
    return function () {
        // If not in execution state
       if(!isRuning){
           // Open Execution Status
           isRuning = true;
           // Define timer
           timeoutFn =(() => {
              fn.apply(this, arguments);
              // Execution completed, execution status closed
              isRuning = false;
           },waitTime)
       }
    }
}

function appendCount(){
    ELem.innerHTML=count++;
}

Elem.addEventListener('mousemove', throttle(appendCount, 3000))

Reference resources

Posted by Hallic7 on Fri, 26 Jul 2019 00:11:12 -0700