The saying “a good question is more important than a right answer” may help us change some of our perceptions.
What problem does anti-shake/throttling solve?
For the user, the process is just an intermediate product of obtaining the result, for example, the user enters the word hello world in the input box, only the complete input word word, and the search result is what the user expects. Like scrolling down to pull more content, mouse movement to draw a movement track… In the scenario of such high-frequency triggering events, if each triggering is responded to one by one, it will consume a lot of performance, waste resources, and have no meaning for users.
Anti – shake/throttling are just two solutions to solve the above problems. The key points of the problem should be made clear here:
- High frequency trigger: the occurrence of high frequency of user’s behavior,
Attention is not limited to the front desk oh, the background can also be
- Ignore procedure: Triggering procedure can be ignored by the user and only respond to the most recent user action
Anti-shake/Throttling: It’s time to show some real technology
Anti – shake algorithm implementation
- Anti – shake: start time from the latest trigger, set a delayed execution time, if triggered again during this period, reset the clock, the execution time is moved back
- Algorithm: Starts the timer, and if triggered during this time, recalculates the time (subtracting the last triggered time, rather than constantly empting/renewing the timer). If the specified interval is exceeded, the system executes it immediately.
// The loadsh.debounce algorithm is implemented with some simplification of the original code for better understanding
function debounce(func, wait, immediate){
var timeout, args, context, timestamp, result;
if (null == wait) wait = 100;
function later() {
// Last equals the last timestamp of the current time differential
Date.now() -10ms
var last = Date.now() -timestamp is about 90ms;if (last < wait && last >= 0) {
// Reset the execution delay wait-last
// If wait:100ms, 100-90 = 10ms
// A delay of 10ms from the last trigger to the execution of fun is exactly the wait interval
timeout = setTimeout(later, wait - last);
} else {
timeout = null;
if(! immediate) { result = func.apply(context, args); context = args =null; }}};var debounced = function(){
// Cache the execution context of the last trigger
context = this;
// Cache the function arguments of the last firing
args = arguments;
// Records the timestamp of the last trigger
timestamp = Date.now();
// Execute immediately
varcallNow = immediate && ! timeout;// To be more specific, let's simulate two user operations
// Once for 0ms and once for 10ms
// ----- The procedure is as follows: -----
// THEREFORE, I pay therefore I am 6. Therefore, I pay therefore I am 6.
// 10ms operation, timeout is the timer ID of the above step, take false value, save the context, parameters, do not do other processing
// This design is very clever and avoids the loss caused by high frequency clearTimeout operation
// Wait for later after the wait is set to later.
// At this point, let's look at the internal details of the Later function
if(! timeout) timeout =setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
context = args = null;
}
return result;
};
return debounced;
};
Copy the code
Throttling algorithm implementation
- Throttling: start time from 0, set a fixed delay execution time, during this period if triggered again, no longer adjust the delay time, to the time to execute the latest trigger function.
- Algorithm: start time, if triggered during this period, save the trigger context, parameters, when the time is up, the execution of the function
function throttle (func, wait) {
var ctx, args, rtn, timeoutID; // caching
var last = 0;
return function throttled () {
ctx = this;
args = arguments;
var delta = new Date() - last;
0ms 5ms 10ms wait = 100ms
// step1: 0ms operation: timeoutID is undefined, and the inverse value is true
// step4: 10ms, save only the context, parameters, do no other processing, and continue to wait for the time, execute the call function
if(! timeoutID)// step2: 0ms operation: delta >= wait is established, execute the call function,timeoutID is assigned the timer id
if (delta >= wait) call();
// step3: 5ms: run timeoutID = setTimeout(call, wait-delta);
else timeoutID = setTimeout(call, wait - delta);
return rtn;
};
function call () {
timeoutID = 0;
last = +new Date(a); rtn = func.apply(ctx, args); ctx =null;
args = null; }}Copy the code
What is the difference between the two solutions?
- Anti – shake: the time to perform the operation by the user goes back, the time reference point is the last trigger time.
- Throttling: The execution time is fixed, the user’s high frequency operation will not affect the previous setting time, when the time is up, the execution. The time reference point is the last execution point
Choose anti-shake or throttling in development?
According to the above differences, the two solutions have their own characteristics and should be selected according to actual business scenarios.
- The intermediate process is only a necessary way to obtain the results. Users pay more attention to the final operation result and can wait for a longer time
- Input Search
- Window’s resize event
- The intermediate process must have specific content response, relative real-time response.
-
Scroll down for more content
-
Mouse movement track/hold down the mousedown
-
Refer to instructions
- Lodash stabilization
- Lodash throttling