Debounce and Throttle Mode

Debounce and throttle are both methods to control the frequency of executing event handling functions. When a function will perform DOM operations or interact with the server and act as a high-frequency event like onscroll, it's necessary to control the execution frequency of the event handling function. Otherwise, it will cause a lot of resource waste, leading to performance degradation. Debounce and throttle do not reduce the number of event triggers, but they improve performance by reducing the execution frequency of event handling functions. Debounce and throttle modes do not belong to the category of the general definition of the 23 design patterns, but they are usually seen as a broad-sense skillful design pattern.

Debounce Mode

Non-immediate Debounce

When the event is continuously triggered, the event handling function is not executed at all. It waits for a period of time after the last triggering before it is executed. The most common example is the search suggestion feature. When a user continuously inputs, the server is not requested for search suggestions until after a certain period of time N milliseconds after the user has finished inputting.

Implementation idea: Cancel the previous delayed call method every time an event is triggered and reset the timer.

function debounce(wait, funct, ...args){
    var timer = null;
    return () => {
        clearTimeout(timer);
        timer = setTimeout(() => funct(...args), wait);
    }
}

window.onscroll = debounce(300, (a) => console.log(a), 1);

Immediate Debounce

When the event is continuously triggered, the event handling function is executed immediately, then it stops executing the event handling function until a period of time after the last event triggering before allowing the execution of the event handling function again.

Implementation idea: Check if the timer exists, if not, execute the event handling function, and then reset the timer regardless of whether the timer already exists.

function debounce(wait, funct, ...args){
    var timer = null;
    return () => {
        if(!timer)  funct(...args);
        clearTimeout(timer);
        timer = setTimeout(() => timer = null, wait);
    }
}

window.onscroll = debounce(300, (a) => console.log(a), 1);

Throttle Mode

When an event is continuously triggered, throttling can dilute the frequency of the event handling function execution. For example, if the onmousemove event is triggered 100 times within 1 second, throttling can make the event handling function of onmousemove trigger only once every 100ms, which means that the event handling function of onmousemove will only be executed 10 times within 1 second.

Timestamp Implementation

Implementation idea: Record the last time the event handling function was executed using a timestamp. When the event is triggered, if the time difference is greater than the execution period, execute the event handling function and update the execution time to the current timestamp.

function throttle(wait, funct, ...args){
    var previous = 0;
    return () => {
        var now = +new Date();
        if(now - previous > wait){
            funct(...args);
            previous = now;
        }
    }
}

window.onscroll = throttle(1000, (a) => console.log(a), 1);

Timer Implementation

Implementation idea: Check if the timer exists, if not, execute the event handling function and reset the timer.

function throttle(wait, funct, ...args){
    var timer = null;
    return () => {
        if(!timer){
            funct(...args);
            timer = setTimeout(() => timer = null, wait);
        }  
    }
}

window.onscroll = throttle(1000, (a) => console.log(a), 1);

Question of the Day

https://github.com/WindrunnerMax/EveryDay

References

https://www.jianshu.com/p/566c66aafa22 https://github.com/mqyqingfeng/Blog/issues/22 https://github.com/mqyqingfeng/Blog/issues/26