Shaking and throttling of events
Stabilization and throttling function is a function of we often used, in the actual development process, such as scroll, resize, click, keyboard and other events are easy to trigger for many times, often triggered the callback caton can lead to a page and jitter, to avoid this, you need to use the throttling and stabilization method to reduce the useless operation and network request, It is also a common problem encountered in the interview, which needs to be firmly mastered.
The nature of damping and throttling
All exist in the form of closures.
They wrap the event callback, cache the time in the form of a free variable, and use setTimeout to control how often the event is triggered.
Save money: The first person calls the shots
The whole point of throttling is that every time you trigger something in a certain amount of time, I only recognize it as the first time, and I respond when the timer ends.
/** * function throttling * action: multiple operations over a period of time, starting only with the first trigger and responding when the timer ends. * scene: For example, enter the search Function * @param fn Event Function to be throttled * @param interval Interval * @returns {Function} */ Function throttle(fn, interval = 500) { let last = 0; return function (... args) { let now = +new Date(); if (now - last > interval) { last = now; fn.call(this, args); }}; } /** * step * accepts a function, and a firing interval, The default time is 500ms * the default value is 0 * Deconstruct multiple arguments into a parameter array * Record the time when the callback is triggered * determine whether the interval between the last time the callback is triggered and this time is larger than the threshold we set * assign the time when the callback is triggered to last, This is used to determine the next time * calls the callback function passed in using call, passing in the argument * */
Use: Use throttles in onScorll
Const better_scorll = 1 const better_throttle (() => {console.log(" a rolling event was fired "); }, 1000); document.addEventListenner("scorll", better_scorll); // Within 1s, no matter how many times the trigger is fired, the response is only given after 1s after the first trigger.
Stabilization: The last man has the last word
The central idea is: I will wait for you until the end. No matter how many times you trigger a pullback in a certain period of time, I only think of the last one
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** * scene: @param fn @param delay @returns {Function} */ Function debounce(fn,) * @returns {Function} */ Function debounce(fn,) delay = 500) { let timer = null; return function (... args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.call(this, args); }, delay); }; } /** * accept a function and a trigger interval. The default time is 500ms * The default value of the timer id is null * Decompose multiple arguments into a parameter array * Determine whether the timer exists, if so, cancel the timer * and create a new timer, When the timer executes: call the passed callback function, passing in the parameter * */. When the timer executes: call the passed callback function with the parameter * */
Use: Use antishake in onScorll
Const better_scroll = debounce(() => console.log(" triggered scroll event "), 1000); document.addEventListener("scroll", better_scroll);
Use Throttle to optimize Debounce
The problem with Debounce is that it is too patient. Imagine, if the user is doing the operation so frequently ———— that he doesn’t wait for the end of the delay set by debounce to do the next operation each time, so each time Debounce regenerates the timer for the user, the callback is delayed over and over again, The user is slow to respond, and the user will have a “page stuck” impression of the page.
In order to avoid self-error, we need to use Throttle’s idea to create a “bottom-line” debounce when you can, but I have my principle: I can regenerate the timer for you during delay time, but as soon as the delay time is up, I have to give the user a response.
This idea of combining Throttle and Debounce has been used by many mature front-end libraries in their enhanced version of Throttle functions.
/** * This function is used to generate a new timer for multiple operations during the delay period, but will be executed only once after the delay period expires. * scene: * @param fn Specifies the event Function for which the operation is to be performed * @param delay specifies the delay time * @returns {Function} */ Function throttle(fn, delay = 500) { let last = 0; let timer = null; return function (... args) { let now = +new Date(); If (now-last < delay) {if (now-last < delay) {// If (timer) clearTimeout(timer); timer = setTimeout(() => { last = now; fn.call(this, args); }, delay); } else {// Execute once if the interval is longer than the set threshold. last = now; fn.call(this, args); }}; } /** * accepts a function and a delay time, which defaults to 500ms * Defines a timestamp and timer ID to start execution, and gives the default value * returns a function and converts the arguments into an array. * if it is less than the interval: * if it is less than: it is clear about the timer, and then regenerate the timer. The timer is directly assigned, then the call function, * greater than: directly assigned, then the call function, */
Use: Use an enhanced version of Throttle in onScorll
Const better_scroll = log(() => console.log(" triggers a scroll event "), 1000); document.addEventListener("scroll", better_scroll);