When performing operations such as window resize, Scroll, and input box content verification, if the event processing function is called at an unlimited frequency, the burden on the browser will be increased, resulting in poor user experience. Debounce and throttle can be used to reduce the frequency of calls without compromising performance.
Debounce: When an event is continuously triggered and no event has been triggered for a certain period of time, the event handler is executed once. If the event is triggered again before the specified time, the delay is restarted. As shown in the following figure, handle is not executed when the Scroll event is continuously triggered. The Scroll event will be delayed when no scroll event is triggered within 1000 milliseconds.
Let’s implement a simple debounce~
Debounce code:
function debounce(fn, wait) { var timeout = null; return function() { if(timeout ! == null) clearTimeout(timeout); timeout = setTimeout(fn, wait); Function handle() {console.log(math.random ()); } // The scroll event window.addeventListener ('scroll', debounce(handle, 1000));Copy the code
The effect is as follows:
We can see that when the Scroll event is continuously triggered, the event handler function Handle will only be called once after scroll stops 1000 milliseconds, that is to say, the event handler function Handle has not been executed during the continuous triggering of the Scroll event.
Function throttling: Ensures that event handlers are called only once in a certain period of time when events are continuously emitted. Throttling popular explanation is like our tap water, as soon as the valve is opened, the water pouring down, holding the good traditional virtue of thrift, we have to turn the tap down a little, it is best to be as we will according to a certain rule in a certain time interval drop by drop. As shown in the figure below, when the Scroll event is continuously triggered, handle is not executed immediately but only once every 1000 milliseconds.
Function throttling can be implemented in two main ways: timestamp and timer. Throttle ~ is then implemented in two separate ways
Throttle code (timestamp) :
var throttle = function(func, delay) {
var prev = Date.now();
return function() {
var context = this;
var args = arguments;
var now = Date.now();
if (now - prev >= delay) {
func.apply(context, args);
prev = Date.now();
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));Copy the code
When the high frequency event is triggered, the first time will execute immediately (to the scroll event binding function and the actual triggering event interval is generally greater than delay, if you must within 1000 milliseconds of the web page to scroll, I can’t o(╥﹏╥) O), and then how frequently trigger events, It is executed only once per delay time. The event will not be executed after the last event is triggered. (The interval between the last event and the penultimate event is less than delay. Why is it less than delay? It is not called high frequency because it is greater than (*╹▽╹*).
The effect is as follows:
Throttle code:
var throttle = function(func, delay) { var timer = null; return function() { var context = this; var args = arguments; if (! timer) { timer = setTimeout(function() { func.apply(context, args); timer = null; }, delay); } } } function handle() { console.log(Math.random()); } window.addEventListener('scroll', throttle(handle, 1000));Copy the code
When the event is triggered, we set a timer. When the event is triggered again, if the timer exists, it is not executed until after the delay time, the timer executes the execution function and clears the timer, so that the next timer can be set. When the event is first raised, the function is not executed immediately, but after a delay of seconds. No matter how frequently events are triggered, they are executed only once per delay time. After the last stop, the function may be executed again due to timer delay.
Throttling with a timestamp or timer is ok. More precisely, you can use a timestamp + timer to execute an event handler immediately after the first event is fired and again after the last event is fired.
Throttle code (timestamp + timer) :
var throttle = function(func, delay) {
var timer = null;
var startTime = Date.now();
return function() {
var curTime = Date.now();
var remaining = delay - (curTime - startTime);
var context = this;
var args = arguments;
clearTimeout(timer);
if (remaining <= 0) {
func.apply(context, args);
startTime = Date.now();
} else {
timer = setTimeout(func, remaining);
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));Copy the code
Inside the throttling function, startTime, curTime and delay are used to calculate remaining time. Remaining <=0 indicates that the remaining event handler is executed, which ensures that the event handler can be executed immediately after the first triggering event and every delay time. If the remaining time is not reached, the remaining time is set to the remaining time. This ensures that the remaining event handler can be executed after the last event. Of course, if remaining fires another event, the timer is cancelled and a remaining is recalculated to determine the current state.
Function stabilization: Combine several operations into one operation. The idea is to maintain a timer that fires after the delay, but if it fires again within the delay, the timer will be cancelled and reset. In this way, only the last operation can be triggered.
Function throttling: causes functions to fire only once in a given period of time. The principle is to trigger the function by judging whether a certain time has been reached.
Difference: Function throttling guarantees that a true event handler will be executed within a specified period of time, no matter how frequently the event is triggered, whereas function buffering only fires once after the last event. For example, in an infinite load scenario, we want the user to make Ajax requests every once in a while while the page is scrolling, rather than asking for data when the user stops scrolling. This scenario is suitable for throttling technology to achieve.