Preface
In development, we often encounter situations where a certain function needs to be triggered frequently, such as:
- Listen to the changes in the scroll bar. When the position of the scroll bar changes, a function needs to be executed.
- Listen to the movement of the mouse. When the position of the mouse changes, a function needs to be executed.
- Listen to the keyboard keys. When a key on the keyboard is pressed, a function needs to be executed.
When users frequentlyUI
When interface operation interaction, for example:Window adjustment
(trigger resize),Page scrolling
,Pull-up loading
(trigger scroll), form button submission, mall rush to buy crazy clicks (triggermousedown
), and real-time search (keyup
,input
), drag and drop
When you frequently trigger the user interface, the event handling function will be triggered continuously. In other words, when there are continuous clicks, pull-up loading, real-time search, frequent operation of DOM elements, request resource loading, etc., performance-consuming operations may cause interface lag, browser crash, page blank, etc.
What solves this problem is function throttling and function anti-shake
Function throttling
definition: Save (reduce) the frequency of triggering event processing functions, triggering execution functions at a certain time continuously. It is a means to optimize the execution of a piece of js code at a high frequency.Features: No matter how frequently the event is triggered, it will ensure that the event handling function is actually executed within the specified interval. Only one function will be executed once in a certain time window. If it is triggered again in the time window, the time will be recalculated.
Application scenarios: Commonly used for multiple consecutive clicks of the mouseclick
Event, mouse movementmousemove
,Drag and drag
,Window size changes
(resize),Pull up the mouse wheel page
(onScroll),Pull-up refresh lazy loading
principle: The function is triggered by determining whether a certain time has been reached. If there is no specified time, the timer will be used for delay. The next event will be reset, which is the interval time execution
Usually high-frequency operations with the user interface include:
- Pull up the mouse wheel page (onScroll), pull down to refresh lazy loading
- Window size change (onresize)
- Drag and drag
If it is a high-frequency operation, if a certain processing is not performed, it will inevitably cause multiple data requests and server pressure. The performance of the code is very inefficient and affects performance. An important means to reduce such frequent operations is to reduce the frequency. Through throttling control, that is, let the core function code be executed once in a certain time and within a certain period of time.
Throttle means ensuring that the core code is executed only once for a period of time
You can think of examples of saving water in life (the Three Gorges Dam has many sluice gates):
High-frequency events are like a large open faucet, with water flowing out continuously, just like code being executed continuously. If not controlled, it will cause a waste of resources. In the corresponding page, if you click the submit button continuously in the form, listen to scroll events, and continuously pull down loading, etc. to request the server's resources.
To throttling, tighten the faucet, reduce its flow frequency, and drop a drop of water every once in a while, thereby saving resources
The manifestation in the code is: setting a certain timer to enable the core function code and partition to be executed
Below is a mouse scroll wheel, throttling operation is implemented: similar to continuous operation, all of which are like this, click the button continuously, pull up and load
Throttle method one: timestamp + timer
/* throttle1 function, throttling implementation method 1: timestamp + timer * @params method,duration The first parameter is the function to be executed when the event is triggered * The second parameter duration is represented as the defined interval time * * Principle: The function is triggered by judging whether a certain time has been reached. If there is no specified time, the timer will be used for delay. The next event will be reset. It is executed at interval time. No matter how frequently the event is triggered, it will ensure that the event within the specified time will definitely execute the real event processing function. * * */ function throttle1(method, duration) { var timer = null; var prevTime = new Date(); // Previous timereturn function() { var that = this, currentTime = new Date(), // Get the current time of the system resTime = currentTime - prevTime; // Time stamp // Print the time difference between the current world and the last world ("Time Difference", resTime); // The current time from the last execution time is less than the set time interval if(resTime < duration) { // Clear the last timer, cancel the queue task called last time, and reset the timer. This ensures that the function will only be triggered once within 500 milliseconds, achieving the purpose of function throttling clearTimeout(timer); timer = setTimeout(function(){ prevTime = currentTime; (that); }, duration) }else { // When the current time from the last execution is greater than or equal to the set time, directly execute the function // Record the execution time prevTime = currentTime; (that); } } } // Event trigger method (function), function throttling 1function handleJieLiu1(){ ("Sales 1"); } var handleJieLiu1 = throttle1(handleJieLiu1, 500); ('mousewheel', handleJieLiu1);
Throttle method 2: Reset a switch variable + timer:
/* * throttle2 function throttling implementation method 2: reset a switch variable + timer * @params method,duration shape parameters are consistent with the above meaning * @return returns an event handler * * The initial value of runFlag is defined during throttle2 execution, and an anonymous function is returned as an event processing function through the closure. * * judge the status of runFlag within the returned function and determine whether to execute the real function method or jump out. After each method is executed, the status of the runFlag will be changed. The status of the runFlag lock will be reset within the specified interval through the timer. * */ function throttle2(method, duration){ // Is there a method to execute within the current time interval? Set a switch mark var runFlag = false; // Return an event handler functionreturn function(e) { // Determine whether there is a method to execute, if there is, do nothing, if true, it will jump out if(runFlag){ return false; } // Start execution runFlag = true; // Add a timer to reset the lock status when the time interval is reached setTimeout(function(){ method(e); // After execution, declare that there is currently no method being executed, which facilitates the next time call runFlag = false; }, duration) } } // Event triggering method (function), function throttling 2function handleJieLiu2(){ ("Sales 2"); } var handleJieLiu2 = throttle2(handleJieLiu2, 500); ('mousewheel', handleJieLiu2);
The above two ways to implement function throttling can prevent users from frequently operating and causing repeated requests to resources.
When the mouse wheel continues to scroll, the execution order of event processing functions is different
When giving a large-scale time, for example: within 1 hour, it will be executed every few minutes, and it will not be executed for more than one hour, it is recommended to use the first function throttling method
If you only require a certain interval of execution, it is recommended to use the second function throttling method
Function anti-shake
definition: Prevent jitter, repeated triggers, frequent operations. The core is to delay the execution of event processing functions, and only the last operation is performed within a certain time interval. That is, when the function is triggered, the function will be triggered again only after the last function is executed for a period of time. For example: Form is submitted multiple times, it is recommended to use anti-shake
In other words, when the event is triggered continuously, the event handler function is not executed, and it is executed only in the last time that a certain stage is triggered continuously, and it follows two conditions.
Have to wait for a while
The time interval of the last trigger must be greater than the set value before it can be executed
Features: Only executed once in a certain period of time
In life, you can imagine that the bus driver only leaves the station after he gets on the bus after he gets on the bus
Application scenarios: Often applied to input box eventskeydown
,keyup
, Search for Lenovo query, and only send Ajax request when the user stops keyboard input
principle: It is to maintain a timer, specified induration
After (delay) time, the event handler function occurs, butduration
If it triggers again within time, the current one will be clearedtimer
Re-time, so that only the last operation event handler function is actually triggered
The specific code is as follows:
/* * Function anti-shake * For example: Assume that the time interval is 500ms, the operation is frequently 5s, and the execution time is less than or equal to the interval of 500ms * Then only one execution was performed in the end, that is, the last execution ended every time * @params method,duration, consistent with the above * * Principle: It maintains a timer, which stipulates the departure time processing function after the duration time, but the current timer will be cleared and re-timed. In this way, only the last operation event processing function will be triggered. * * It is generally used for input box events. Common scenarios are form searches or Lenovo query. If you do not use anti-shake, you will send requests continuously, increasing the pressure on the server. After using anti-shake, the request will be sent only after the user enters the keywords to be queryed. This is how Baidu Search is implemented. * * */ function debounce(method, duration) { var timer = null; return function(){ var that = this, args = arguments; // If a method is executed within an interval between this call, the execution of the method will be terminated if(timer) { clearTimeout(timer); } // Start executing this call timer = setTimeout(function(){ (that,args); }, duration) } } // Event triggering method (function), anti-shakefunction handleFangDou(){ ("Function anti-shake",new Date()); } var handleFangDou = debounce(handleFangDou, 500); var oInput = ("#input"); // Get input element('keyup',handleFangDou);
As shown in the above input box effect, every time the input box is entered, the event handling function is executed when the keyboard pops up, instead of triggering the event handling function when typing content.
Similarly, when search engines and form association query functions, Ajax data requests are not made at the same time based on the letters, numbers, and contents typed by the user. If a data request is triggered every time a letter is typed, it will consume performance. The query request should be triggered when the user stops input. At this time, the function is used to prevent the shadowing.
The multiple submissions of forms, Baidu search, etc. are all achieved by using anti-shake.
summary:
Common points: They all solve performance problems such as frequent operation trigger event handling functions, causing page lag and not smoothness. They all improve performance by setting delay timer logic to reduce the number of http requests and save request resources
Differences: Function throttling, the event processing function is executed within the interval, while the function is anti-shake, and only the last operation is performed within a certain time interval
Directly introduce lodash library
If you do not implement it manually, you can install it directlyyarn add lodash
, then introduce
// Function interfacenpm i -S ; import throttle from ''; // Introduce the library // Event trigger method (function), throttlingfunction handleThrottle(){ ("Trust of functions",new Date()); } throttle(handleThrottle, 500); // Pass the trigger event handling function as the first parameter, and the second parameter is the interval time, here is 500 milliseconds
The following is the implementation of function anti-shake
Pass in the terminalnpm
orcnpm
oryarn
Install third-party libraries in a way
npm i -S or cnpm install -S
Use in components
import debounce from ''; // Function anti-shake function handleDebounce() { ("Function anti-shake", new Date()); } debounce(handleDebounce, 500);
Implement function anti-shake natively
// Encapsulate a debounce function yourself for anti-shake debounce(method, duration) { var timer = null; /*return function(){ var that = this, args = arguments; // If a method is executed within an interval between this call, the execution of the method will be terminated if(timer) { clearTimeout(timer); } // Start executing this call timer = setTimeout(function(){ (that,args); }, duration) }*/ // The above return anonymous function can be used with the Es6 arrow function. The following writing method is equivalent to the above and the simplest way to write it, but it is not as easy to understand as the above code. return (...args) => { clearTimeout(timer); timer = setTimeout(() => method(...args), duration) } }
Of course, it can still be optimized for the above code. For callback functions, in Es6, they are often used to process arrow functions, which will save a lot of trouble
For example: this pointing problem
As shown below:debouce
The easiest package of functions
You can also place the initial value of the timer above in the debouce function as the third parameter setting, it is also OK
debounce(method, duration, timer = null) { return (...args) => { clearTimeout(timer); timer = setTimeout(() => { method(...args) }, duration) } }
If you encapsulate it yourselfthrottle
anddebounce
Functions can be encapsulated separately into a file and exposed to the outside. Where they are needed,import
Just introduce it, just call it directly in the code
Create a in the root directory (whichever is yours)pass
export default
Exposed
/* * @authors Chuanchuan (itclancode@) * @ID suibichuanji * @date 2023-10-19 @desc Encapsulate throttling function * @param method,duration:method event handler function,duration: interval time * @return Anonymous function * Principle: Trigger the function by judging whether it has reached a certain time. * If there is no specified time, use the timer for delay, and the next event will reset the timer. * It is executed at intervals, no matter how frequently the event is triggered * They will ensure that the actual event handling function will be executed within the specified event. * */ function throttle(method, duration) { var timer = null; var prevTime = new Date(); // Previous time return function() { var that = this, currentTime = new Date(), // Get the current time of the system resTime = currentTime - prevTime; // Time stamp // Print the time difference between the current world and the last world ("Time Difference", resTime); // The current time from the last execution time is less than the set time interval if (resTime < duration) { // Clear the last timer, cancel the queue task called last time, and reset the timer. This ensures that the function will only be triggered once within 500 milliseconds, achieving the purpose of function throttling clearTimeout(timer); timer = setTimeout(function() { prevTime = currentTime; (that); }, duration) } else { // When the current time from the last execution is greater than or equal to the set time, directly execute the function // Record the execution time prevTime = currentTime; (that); } } } export default throttle;
Then import it in the throttling file that needs to be used
import throttle from './throttle'; throttle(Event trigger handling function, 1000);
Similarly, if you encapsulate it yourselfdebounce
The function's anti-shake is removed separately and packaged into a function, throughexport
Exposed to the outside world for call
/** * * @authors Chuanchuan (itclancode@) * @ID suibichuanji * @date 2023-10-19 * @version $Id$ * @description Function anti-shake * @param { method, duration} [method is event handling function, duration is delay time] * Principle * Principle: It maintains a timer and specifies the departure time processing function after the duration time * However, if the change starts again within the duration time, the current timer will be cleared and re-timed. * In this way, only the last operation event handler function will be actually triggered * * Generally used for input box events, commonly used scenarios are form search or association query. * If you do not use anti-shake, you will send requests continuously, increasing the pressure on the server * After using anti-shake, the request will be sent after the user enters the keyword to be queryed. This is how Baidu Search implements it. */ function debounce(method, duration) { var timer = null; return function(){ var that = this, args = arguments; // If a method is executed within an interval between this call, the execution of the method will be terminated if(timer) { clearTimeout(timer); } // Start executing this call timer = setTimeout(function(){ (that,args); }, duration) } } export default debounce;
How to prevent function calls from being too fast (function throttling, two ways) or too many times (function anti-shake), respectively, using native JS to implement them in third-party libraries
The throttling and anti-shaking of functions are methods to improve performance at the front end. Although there are only a few lines of code, during interviews, you are always asked to write by hand. Many times, you may not be able to write without searching.
In actual development, the throttling of functions and function anti-shake are also relatively frequent, which shows that its importance is self-evident
The above is the detailed content of the native implementation of anti-shake and throttling in JavaScript functions and the use of third-party libraries. For more information about anti-shake and throttling in JavaScript functions, please pay attention to my other related articles!