define

In JavaScript, function anti-shake and throttling is not a new topic, and there are numerous articles corresponding to it, but it is not as clear as doing it yourself and writing it. I have been in a relatively hazy impression of anti-shake and throttling before this, just this time, write this article to record the difference between the two.

  • Stabilization effect

    1 seconds. Whenever a new trigger is generated: time from 0.

  • The throttling effect

    1 seconds. As long as a new trigger is generated: invalid until the previous action is completed.

scenario

Having said that, let’s see how to use it first. Suppose we have a scenario requirement that looks like this:

We need to monitor the mouse movement of the page, which triggers mousemove frequently, and mousemove has some complex calculations in it. Let’s assume that the event needs to do 100,000 loop insertions to simulate complex calculations. This can lead to a serious performance problem. Mousemove is so industrious that we don’t need a “just-in-time” trigger that would take up time for other operations, such as our page getting stuck. So we need to introduce anti-shake and throttling.

Let’s take a look at the simulated complex operation we’re about to perform:

let arr = [];
for (let i = 0; i <= 100000; i++) {
  arr.push(Math.random())
}
arr.sort((x, y) = > y - x)
console.log(arr.join())
Copy the code

(Redundant interpretation: Random generation of 100,000 numbers, arranged from the largest to the smallest, and finally concatenated output)

As you can see the calculation is time-consuming, let’s go to the code below mousemove:

 function handle({ clientY, clientX }) {
        let arr = [];
        for (let i = 0; i <= 100000; i++) {
            arr.push(Math.random())
        }
        arr.sort((x, y) = > y - x)
        console.log(arr.join())
		document.body.innerText = `x:${clientY},y:${clientX}`
    }
    document.addEventListener('mousemove', handle)
Copy the code

The Handle function handles the mousemove operation and displays the mouse coordinates on the page.

It can be found that the page is already a little bit stagnant, we will use anti-shake and throttling to optimize the current page experience.

Image stabilization

Code:

function debounce(fn, time) {
        let timer;// Record the timer
        return function(event) {// Return a new function
            clearTimeout(timer)// If it is triggered again, clear the last timer
            document.body.innerText = 'Mouse stop to show results'
            timer = setTimeout(() = > {// The next time the event loop is triggered, the timer ID is recorded for cleaning up.
                fn(event)
            }, time)
        }
    }
document.addEventListener('mousemove', debounce(handle, 100))// Pass the handle function and trigger 100 milliseconds later
Copy the code

After the display on the page, you can see that when the mouse continues to slide, the page does not move, but once the mouse stops for 100 milliseconds, it starts to display the content.

The throttle

Code:

 function throttle(fn, time) {
        let flag = false;// Set the flag bit
        return function(event) {
            if (flag) return false;// If the flag contains the timer ID, it indicates that there was a task before. Cancel the task.
            flag = setTimeout(() = > {// Record the task ID
                fn(event)
                flag = false;// When the task is completed, the flag bit is restored
            }, time)
        }
    }
document.addEventListener('mousemove', throttle(handle, 100))// Pass the handle function and trigger 100 milliseconds later
Copy the code

Page display can be found: when the mouse slide, the page has been calculating, but no matter how to slide, will be in accordance with the specified time frequency, not a large number of trigger.

Of course, the implementation of anti-shock and throttling is not necessarily the only way I show you, the code is flexible, such as the second throttle method:

function throttle2(fn, time) {
        let begin = new Date(a);// Record the time
        return function(event) {
            if (new Date() - begin < time) return false;// Subtract time to see how much difference, do not meet the time directly return
            fn(event)
            begin = new Date(a)// Reset the record time for the next comparison}}Copy the code

Go back to the diagram at the beginning

Combination of anti-shake and throttling:

function throttle(fn, time, fn2, time2) {
        let flag = false;// Throttle flag
        let timer;// The anti-shake timer flag
        return function(event) {
            clearTimeout(timer)// Clean up the timer
            if (flag) return false;
            flag = setTimeout(() = > {
                fn(event)// The page needs to display content in real time. UI updates that do not require a lot of calculation are placed here
                flag = false;
                timer = setTimeout(() = > {// Perform complex operations in delay, so that there is time to perform complex operations while the mouse is still.
                    fn2()
                }, time2)
            }, time)
        }
    }
    
     function handle({ clientY, clientX }) {
        document.body.innerText = `x:${clientY},y:${clientX}`
    }

    function handle2() {
        let arr = [];
        for (let i = 0; i <= 100000; i++) {
            arr.push(Math.random())
        }
        arr.sort((x, y) = > y - x)
        console.log(arr.join())

    }
    document.addEventListener('mousemove', throttle(handle, 10, handle2,50))
Copy the code
  • The above code can be a good solution to page lag, mouse movement at the same time, need to move to a place to do a lot of calculations.

conclusion

  • Here is a brief summary of the use of anti-shake and throttling in this scenario:
    • Anti-shock: Don’t let complex calculations run too often when they are appropriate, wait for the page to “cool off” before performing them.
    • Throttling: It must be done at regular intervals for high-priority tasks such as the UI.

Think and write more. It’s easy to tell the difference