1. Introduction

Generally speaking, this paragraph is mainly about the general overview of some knowledge, is not so important, equivalent to the summary of the article. However, there are some unusual, such as the concept of anti-shake and throttling understanding is very important, very important.

1.1 Causes

The first thing to point out is why these two ideas come into being.

1. Since the naked eye can only distinguish certain frequency changes, that is to say, a change of 1000 times within 1s is the same as a change of 60 times. Similarly, it can be analogized to JS code. The code doesn’t have to execute very many times in a given amount of time. A certain frequency is enough. Because the more you run, the same thing happens.

2. The client performance is faulty. As we all know, at present compatible with the front-end is still quite important, and the main point of compatibility lies in low-end models, so it is necessary for us to control the number of js code execution in a reasonable range. Not only can save browser CPU resources, but also can make the page browse more smoothly, not because of the execution of JS and the occurrence of lag.

This is where function throttling and function stabilization come in.

1.2 Concept Understanding

The above mentioned so much, just to explain why there are two kinds of implementation of anti-shake and throttling, the following image to understand the difference between the two ideas, a lot of times I will confuse these two ideas, so this time specially want to remember the way.

1. Function throttling refers to the js method running only once in a certain period of time.

Throttling Throttling means to save the flow of water, like when a faucet is running. We can manually reduce the flow of water (for a certain period of time), but it will always flow.

Of course, there is a figurative metaphor of saving money by increasing source. For example, we spend less money this month (for a certain period of time), but we need to spend money every day.

2. Function stabilization Only execute the code once when there is enough idle time.

Take a bus in life, for example, is a certain period of time, if someone has to swipe the card to get on the bus, the driver will not drive. A driver only drives when someone else’s card is gone. (In fact, as long as you remember the idea of throttling can be determined by elimination method throttling and anti-shake)

Code 2.

2.1 if you

The above explanation is intended to vividly illustrate the idea and difference between anti-shake and throttling. Now we need to explore anti-shake further at the code level.

First of all, the most important thing to do before writing code is to think in your mind what logic this code needs to implement. Here is the logic of the code.

You may trigger the event, but I must be n seconds after the event triggered, if you trigger the event within n seconds of an event triggered, then I will take the time of the new event as the standard, n seconds after the execution, in short, is waiting for you to trigger the event, n seconds no longer trigger the event, I will execute!

Ok, we can easily write the first version of the anti-shake code based on the above ideas.

function debounce(func, waitTime) {
  var timeout;
  return function () {
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(func, waitTime);
  }
}
document.querySelector('#app').onmousemove = debounce(fn, 1000);
Copy the code

The above snippet of code is the original anti-shake code.

As you can see, the above lines of code use the knowledge of closures, mainly to preserve the timeout variable after the function is executed.

If you want a function to finish executing and one of its variables (timer) still exists, you can use closures to declare the variables in the parent scope and put other statements in the child scope and return them as a function. The following examples use closures to solve the problem of preserving variables.

There is also a small partner may have doubts. Why do I have to return a function here. It’s actually easy to understand, so let’s look at the following code

var timeout;
function debounce(func, waitTime) {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(func, waitTime);
}
container.onmousemove = debounce(getUserAction, 1000);
Copy the code

I manually removed the return from debounce and then placed it in a global variable to preserve timeout. These lines look similar, but you can run through this code and see that Debounce only executes once!!

In fact, the reason we return a function in debounce is because onMousemove requires a bound function, and our test code will only return undefined after executing once

container.onmousemove = debounce(getUserAction, 1000);
container.onmousemove = undefined;
Copy the code

Of course, events are not properly bound. If you want to make sense of it, you can actually bind it like this

var timeout;
function debounce(func, waitTime) {
  if (timeout) {
    clearTimeout(timeout);
  }
  timeout = setTimeout(func, waitTime);
}
container.onmousemove = () => {
  debounce(getUserAction, 1000);
}
Copy the code

All of the following methods are exactly the same as the first one.

However, in this version of the code, we print this and event objects in fn and find something wrong.

As you can see from the figure above, the this and event objects in fn are not expected, so we need to manually pass this and event objects to the fn function. Hence the following second version of the anti – shake function.

function debounce(func, waitTime) {
  var timeout;
  return function () {
    var context = this,
        args = arguments;
    if (timeout) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(function () {
      func.apply(context, args)
    },  waitTime); }}Copy the code

The fn function uses apply to pass this and event objects to fn.

2.2 the throttle

Let’s move on to the code logic for throttling.

With timestamps, when the event is triggered, we take the current timestamp, subtract the previous timestamp (initially set to 0), execute the function if it is greater than the period set, then update the timestamp to the current timestamp, if it is less than the current timestamp, do not execute.

Ok, based on the above logic, we can easily write the first version of the throttling function.

function throttle(func, waitTime) {
    var context,
        args,
        previous = 0;
    return function() {
        var now = + new Date();
            context = this;
            args = arguments;
        if (now - previous > waitTime) { func.apply(context, args); previous = now; }}}Copy the code

Or we can actually use timers to throttle.

When the event is triggered, we set a timer, and when the event is triggered, if the timer exists, it is not executed until the timer is executed, and then the function is executed to clear the timer so that the next timer can be set.

function throttle(func, waitTime) {
    var timeout,
        previous = 0;
    return function() {
        context = this;
        args = arguments;
        if(! timeout) { timeout =setTimeout(function(){
                timeout = null;
                func.apply(context, args)
            }, waitTime)
        }

    }
}
Copy the code

3. Turn knowledge into skill

In 2018, my biggest insight is to try to translate what I have learned into skills (from Lao Yao [juejin.cn/post/684490…] (five cognitive harvest in 2018, all strong | Denver annual essay))

Knowledge can be learned, but skills can only be learned.

In the above two parts, we are learning the reasons for the emergence of anti-shake and throttling, the corresponding concepts and the ideological logic of implementation. These are all knowledge. Now let’s turn the knowledge we have learned into skills and strive to become a part of our own projects.

For utility functions such as stabilization and throttling, we can simply put them in public files and call them where needed.

The core use of anti-shake and throttling is to optimize code performance, which can be used in many ways, such as input field validation, lazy image loading, various DOM events that are frequently triggered, and so on.

Below is my own simulation of baidu search button Sprite, figure 1 shows that there is no anti-shake search. I found that THE keyword initiated N times of requests, and then changed a line of code to add anti-shake, and the request situation became Figure 2. The effect is obvious.

this.debounce(this.getData, 1000)();
Copy the code

Author’s brief introduction

Dao Feng, front-end development engineer of Tongban Street, joined the team in April 2018, and is now mainly responsible for the development of APP terminal project on the operation side.