Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

What are function anti-shake and throttling?

Function anti-shake and function throttling: Some events in JS, such as browser resize, Scroll, mouse mousemove, mouseover, input keypress and other events, will constantly call the callback function bound to the event when triggered, which greatly wastes resources. Reduces front-end performance. To optimize the experience, you need to limit the number of calls to these events.

Why do function tremble and throttling?

All of them are to limit the execution frequency of the function, so as to optimize the response speed to keep up with the triggering frequency caused by the excessively high triggering frequency of the function, and to prevent the phenomenon of delay, false death or stuttering caused by frequent triggering of the same event in a short time.

Function image stabilization

The callback is executed n seconds after the event is triggered, and if it is triggered again within n seconds, the timer is reset.

According to the idea of function anti-shake design of the first version of the simplest anti-shake code:

var timer; // Maintain the same timer
function debounce(fn, delay) {
    clearTimeout(timer);
    timer = setTimeout(function(){
        fn();
    }, delay);
}
Copy the code

Test the anti-shake function with OnMousemove:

// test
function testDebounce() {
    console.log('test');
}
document.onmousemove = () = > {
  debounce(testDebounce, 1000);
}
Copy the code

The debounce function in the above example is the anti-shock function. When the mouse moves in the document, the callback testDebounce is executed 1s after the last trigger of onMousemove. If we keep moving the mouse around in the browser (for example, 10 seconds), testDebounce will take 10 + 1s to execute (because of clearTimeout(timer)), and this is function stabilization.

In the above code, there is a problem that the var timer can only be in the parent scope of setTimeout, which is the same timer. In order to facilitate the call of the anti-shock function and the parameter passing of the callback function fn, we should use closures to solve these problems.

Optimized code:

function debounce(fn, delay) {
    var timer; // Maintain a timer
    return function () {
        var _this = this; // call debounce to execute scoped this
        var args = arguments;
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(function () {
            fn.apply(_this, args); // Apply to the object that called debounce, equivalent to _this.fn(args);
        }, delay);
    };
}
Copy the code

Test cases:

// test
function testDebounce(e, content) {
    console.log(e, content);
}
var testDebounceFn = debounce(testDebounce, 1000); // The buffeting function
document.onmousemove = function (e) {
    testDebounceFn(e, 'debounce'); // Pass parameters to the anti - shake function
}
Copy the code

With closures, you solve the problem of passing arguments and encapsulating the anti-shock function so that functions that need to be anti-shock can be passed to Debounce anywhere.

Function of the throttle

Once in a while, the function is executed.

  • The timer implements throttling functions:

Please look carefully at the code difference with the anti – shake function

function throttle(fn, delay) {
    var timer;
    return function () {
        var _this = this;
        var args = arguments;
        if (timer) {
            return;
        }
        timer = setTimeout(function () {
            fn.apply(_this, args);
            timer = null; // Clear the timer after fn is executed after delay, and throttle triggers to enter the timer
        }, delay)
    }
}
Copy the code

Test cases:

function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // throttling function
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // Pass parameters to the throttling function
}
Copy the code

In the example above, if we kept moving the mouse in the browser (say, 10 seconds), we would perform testThrottle every 1 second for 10 seconds, which is function throttling.

The purpose of function throttling is to limit functions to one execution at a time. Therefore, the timer implements the throttling function by using a timed task, which is executed in a delayed method. If a method is fired during the time delay, it exits the method directly. Thus, the implementation function is executed only once at a time.

According to the principle of function throttling, we can also implement function throttling without relying on setTimeout.

- Timestamp implements the throttling functionCopy the code
function throttle(fn, delay) {
    var previous = 0;
    // Returns a function using a closure and uses the variable previous outside the closure
    return function() {
        var _this = this;
        var args = arguments;
        var now = new Date(a);if(now - previous > delay) { fn.apply(_this, args); previous = now; }}}// test
function testThrottle(e, content) {
    console.log(e, content);
}
var testThrottleFn = throttle(testThrottle, 1000); // throttling function
document.onmousemove = function (e) {
    testThrottleFn(e, 'throttle'); // Pass parameters to the throttling function
}
Copy the code

Its implementation principle, by comparing the time difference between the last execution time and the current execution time and the size of the interval time, to judge whether to execute the function. If the time difference is greater than the interval, the function is executed immediately. Update the last execution time.

Compare them

Similarities:

  • Both can be implemented using setTimeout.
  • The goal is to reduce the frequency of callbacks. Saves computing resources.

Difference:

  • Function stabilization, handling callbacks after a sequence of operations, using clearTimeout and setTimeout. Function throttling, used to improve performance during high frequency events that are executed only once at a time during a continuous operation.
  • Function chattering focuses on events that are fired continuously for a certain period of time and only execute once last, while function throttling focuses on executing only once in a period of time.