Throttle and debounce for JavaScript Performance Optimization)

Source: Internet
Author: User
This article mainly introduces information about the functions throttle and debounce of JavaScript performance optimization, which is very good and has reference value, if you need a function, you can refer to the function throttling. Simply put, it means that a function cannot be called continuously at a very short interval. Only after the execution of the function passes the specified interval, can be called next time.

The principle of function Throttling is quite simple. It is estimated that everyone has come up with it, that is, the timer. When I trigger a time, setTimout will delay the event for a while before execution. If the event is triggered again within this time interval, we will clear the original timer, then setTimeout a new timer will be delayed for a while, that's all.

In the following scenarios, events are often triggered, and DOM operations, resource loading, and other heavy behaviors are frequently executed, causing UI pauses or even browser crashes.

1. resize and scroll events of the window object

2. mousemove event during dragging

3. Shooting the mousedown and keydown events in the game

4. text input and automatic keyup events

In fact, most of the actual requirements for window resize events are to stop and change the size n milliseconds before subsequent processing. Most of the requirements for other events are to be processed at a certain frequency. To address these two needs, there are two solutions: debounce and throttle.

Throttle and debounce are two solutions to solve the mismatch between request and response speed. The difference between the two lies in choosing different policies.

Throttle and other time interval execution functions.

If an event is triggered again within the time interval t of debounce, the function is re-scheduled until the stop time is greater than or equal to t.

1. Simple implementation of the throttle Function

function throttle(fn, threshhold, scope) { threshhold || (threshhold = 250); var last, timer; return function () { var context = scope || this; var now = +new Date(), args = arguments; if (last && now - last + threshhold < 0) { // hold on to it clearTimeout(deferTimer); timer = setTimeout(function () { last = now; fn.apply(context, args); }, threshhold); } else { last = now; fn.apply(context, args); } };}

Call Method

$('body').on('mousemove', throttle(function (event) {console.log('tick');}, 1000));

Ii. Simple implementation of the debounce Function

function debounce(fn, delay) { var timer = null; return function () { var context = this,args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); }, delay); };}

Call Method

$('input.username').keypress(debounce(function (event){// do the Ajax request}, 250));

3. Simple encapsulation implementation

/*** Throttle * @ param fn, wait, debounce */var throttle = function (fn, wait, debounce) {var timer = null, // timer t_last = null, // context, // context args, // parameter diff; // return funciton () {var curr = + new Date (); var context = this, args = arguments; clearTimeout (timer); if (debounce) {// if debounce timer = setTimeout (function () {fn. apply (context, args) ;}, wait) ;}e Lse {// if it is throttle if (! T_last) t_last = curr; if (curr-t_last> = wait) {fn. apply (context, wait); context = wait = null; }}}/*** debounce * @ param fn, wait */var debounce = function (fn, wait) {return throttle (fn, wait, true );}

Summary: these two methods are suitable for repeated events, such as mousemove, keydown, keyup, keypress, and scroll.
If you only bind native events and do not control them, the browser will be stuck and the user experience will be poor. To improve js performance, it is recommended to use function throttling or function deshake to control the above and similar events.

4. underscore v1.7.0 source code analysis

1. _. throttle Function

_. Throttle = function (func, wait, options) {var context, args, result; var timeout = null; // timer var previous = 0; // if (! Options) options ={}; var later = function () {previous = options. leading === false? 0: _. now (); timeout = null; result = func. apply (context, args); if (! Timeout) context = args = null;}; return function () {var now = _. now (); // whether to execute if (! Previous & options. leading = false) previous = now; // a remaining concept is introduced here: How long is there to execute the event var remaining = wait-(now-previous ); context = this; args = arguments; // remaining <= 0 considering that the event is re-triggered after it is stopped, or // when the difference between wait and wait occurs, the event will be triggered immediately // remaining> wait does not take into account the corresponding scenario // because now-previous is always positive and not 0, then // remaining will always be smaller than wait, there is no situation bigger than wait. // It is probably safe. In this case, if (remaining <= 0 | remaining> wait) {if (timeout ){ ClearTimeout (timeout); timeout = null;} previous = now; result = func. apply (context, args); if (! Timeout) context = args = null; // whether to trace} else if (! Timeout & options. trailing! = False) {timeout = setTimeout (later, remaining) ;}return result ;};};

As shown in the preceding figure, underscore considers many situations: options. leading:

Whether to execute the first time. The default value is true, indicating that the first time will be executed. If {leading: false} is passed in, the first execution of options will be disabled. trailing: whether to execute the last time. The default value is true, indicating that the last execution will be performed. The input {trailing: false} indicates that the last execution is not performed. The so-called first execution is when an event is triggered, do you want to trigger the event first? If you want to, previous = 0, and remaining is a negative value, the function is called immediately to determine whether to execute the last time. After the event ends, this method is triggered last time. If you want to execute this method, set the timer, that is, it will be executed again after the event ends. Remianing> wait indicates that the client time has been modified.

2. _. debounce Function

_. Debounce = function (func, wait, immediate) {// The default value of immediate is false var timeout, args, context, timestamp, result; var later = function () {// multiple calls when the wait specified time interval period _. the function returned by debounce will continuously update the value of timestamp, resulting in the last <wait & last> = 0 always being true, so as to start a new timer to run the func var last = _. now ()-timestamp; if (last <wait & last> = 0) {timeout = setTimeout (later, wait-last);} else {timeout = null; if (! Immediate) {result = func. apply (context, args); if (! Timeout) context = args = null ;}}; return function () {context = this; args = arguments; timestamp = _. now (); // when this method is called for the first time and immediate is true, call the func function var callNow = immediate &&! Timeout; // if (! Timeout) timeout = setTimeout (later, wait); if (callNow) {result = func. apply (context, args); context = args = null;} return result ;};};

_. What's amazing about debounce's implementation is that it uses recursive start timers instead of calling clearTimeout to adjust the delayed execution of the function called func.

The above section describes the functions throttle and debounce for JavaScript performance optimization. I hope this will be helpful to you, if you have any questions, please leave a message and the editor will reply to you in time. I would like to thank you for your support for PHP chinnet!

For more articles about throttle and debounce, see PHP!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.