preface

Both anti-shake and throttling are designed to solve performance problems caused by frequent triggering of a function within a short period of time. For example, the trigger frequency is too high to keep up with the response speed, resulting in delays, suspended animation or stalling.

And in the actual development, most can meet, so master this knowledge point is very necessary. However, they address different business requirements, so the rationale for their implementation is different. Let’s take a look.

Debounce

introduce

When the event is triggered for n seconds, the event handler is executed. If the event is raised again within n seconds, the timer is restarted and the event handler is not executed.

The idea is to maintain a timer that is supposed to trigger a callback after the delay, but if it is triggered again within the delay, the timer will be cancelled and reset. In effect, you combine several operations into one operation, meaning that only the last operation will be triggered.

Application scenarios

  1. Search, after the user enters the character, then sends the request

  2. With anti-shake, the resize or Scroll event is triggered only once when the user repeatedly zooming in or out of the browser window or scrolling through a document.

const debounce = function (func, delay) {    
    let timerId = null;    
    return function() {      
        timerId && clearTimeout(timerId);
        timerId = setTimeout(function() {
            func.apply(this.arguments); }, delay); }}function handle() {    
    console.log('It's rolling again'); 
}

window.addEventListener('scroll', debounce(handle, 1000));
Copy the code

After putting the above anti-shake code into practice, we can see that when the Scroll event is continuously triggered, handle will only be called once after scroll stops for 1000 milliseconds. In other words, handle is not executed during the scroll event continuously triggered.

Throttle

introduce

Ensure that event handlers are called only once in a given period of time when events are continuously fired. Its implementation principle: is to trigger the callback function by judging whether a certain time has been reached.

Application scenarios

  1. Click a function button multiple times in a certain amount of time.

  2. The page loads indefinitely. Instead of asking for data just by scrolling, make Ajax requests every once in a while when you need the user to scroll the page.

  3. Resize allows you to zoom in and out of the browser window.

case

Function throttling implementation: timestamp, timer, timestamp + timer.

The time stamp version

const throttle = function(func, delay) {let prev = Date.now();return function() {let now = Date.now();if(now-prev >= delay) {func. Apply (this.arguments); prev =Date.now(); }else {
        console.log('Call time not sufficient'); }}}function handle() {console.log('It's rolling again');        
}

window.addEventListener('scroll', throttle(handle, 1000));
Copy the code

Timestamps: There are two things to note.

  1. If the page has not finished loading, a high frequency event (in this case, scrolling) is triggered, the first time immediately. The load time is longer than the delay.

  2. If the difference between the last callback and the last callback is less than delay, the last callback is not triggered.

The timer version

const throttle = function(func, delay) {            
    let timer = null;            
    return function() {                                
        if(! timer) { timer =setTimeout(function() {                    
                func.apply(this.arguments);                     
                timer = null;                    
            }, delay);                
        } else {
            console.log('Call time not sufficient'); }}}function handle() {            
    console.log('It's rolling again');         
}        
window.addEventListener('scroll', throttle(handle, 1000));
Copy the code

When an event is first raised, the event handler is not called immediately, but only after delay milliseconds. After that, no matter how frequently the event is triggered, it is called once every delay millisecond. When the last trigger stops, the handler is called again because the timer is delayed by milliseconds.

Timestamp + timer

Looking at the throttling of the timestamp or timer implementation above, we see that using either of them alone has certain drawbacks. However, when we use the two together, you can see that it can execute the event handler immediately after the first event and once after the last event.

const throttle = function(func, delay) {     
    let timerId = null;     
    let startTime = Date.now();
    
     // startTime: startTime currentTime: currentTime delay time: delay remaining time: remainTime
    return function() {         
        let currentTime = Date.now();             
        let remainTime = delay - (currentTime - startTime);                         
        clearTimeout(timerId);              
        if (remainTime <= 0) {                    
            func.apply(this.arguments);                    
            startTime = Date.now();              
        } else {                    
            timerId = setTimeout(func, remainTime); }}}function handle() {      
    console.log('It's rolling again');
} 

window.addEventListener('scroll', throttle(handle, 1000));
Copy the code

When remainTime <= 0, the event handler will be executed, which ensures that the event handler will be executed immediately on the first time the event is triggered and every delay time.

When remainTime > 0, the delay of remainTime is set, and the event handler function is executed. This ensures that an event handler can still be executed after the last event is fired. If the event is triggered again during remainTime, cancel the current timer and start the time again.

conclusion

Anti – shake and throttling can effectively reduce the loss of browser engine, prevent page jam jam phenomenon, recommend students to master.