Detailed Explanation and Method Summary of JavaScript Function Throttling

  • 2021-07-18 06:36:43
  • OfStack

Detailed Explanation of JavaScript Function Throttling

There is only one UI thread for a web page in the browser, which can handle the rendering of the interface and the execution of the JavaScript code of the page at the same time (under simple extension 1, the browser or JavaScript running environment is not a single thread, such as ajax asynchronous callback, hybrid communication with native within the framework, event queue, CSS running thread, etc. all belong to multi-threaded environment, but ES6 introduces Promise class to reduce some asynchronous situations). Therefore, when JavaScript code runs a method with a large amount of computation, it may block UI thread, and if it is small, it will cause the user's response to jam. In serious cases, the browser will prompt whether the page is forced to close without response. For example, page scrolling events of web pages, sliding and scaling events of mobile devices, etc. Even if there are no serious performance problems, we should split the large-scale processing time that will be triggered many times in a short time from the perspective of performance optimization.

How to effectively avoid UI thread running too long code is a problem that all user interaction applications need to consider. The same problem can be solved in client Android by using UI main thread to open sub-threads to decentralize calculation. Correspondingly, js can also be decentralized by introducing webWorker, but there is a simpler and effective method in js: function throttling. The core technique of using function throttling is to use timer proration. There are roughly two ways to realize it.

Method 1

1. The idea of this implementation is easy to understand: set a time interval of 1, such as 50 milliseconds, set a timer based on this time, clear this timer when the interval between the first trigger event and the second trigger event is less than 50 milliseconds, and set a new timer, and so on, until there is no repeated trigger within 50 milliseconds after one event is triggered. The code is as follows:


function debounce(method){ 
  clearTimeout(method.timer); 
  method.timer=setTimeout(function(){ 
   method(); 
  },50); 
} 

There is one problem with this design: Events that should have been triggered multiple times may end up only once. Specifically, if the user scrolls too fast or the throttling interval of the function set by the program is too long, the final scrolling event will appear as a very sudden jump event, and the intermediate process will be cut off by throttling. This example is a bit exaggerated, but throttling in this way will eventually obviously feel that the program is "more abrupt" than when it is not throttled, which is very bad for the user experience. There is a design idea to make up for this defect.

Method 2

2. The idea of the second implementation is slightly different from that of the first one: set an interval time, such as 50 milliseconds, to stably separate the event triggering situation based on this time, that is to say, if multiple events are triggered continuously within 100 milliseconds, they will only be executed stably once in 50 milliseconds. The code is as follows:


var oldTime=new Date().getTime(); 
var delay=50; 
function throttle1(method){ 
  var curTime=new Date().getTime(); 
  if(curTime-oldTime>=delay){ 
   oldTime=curTime; 
   method(); 
  } 
} 

Method 2 may perform more times than Method 1 (sometimes meaning more requests for background, i.e. more traffic), but it is a good solution to the defect of method 1 clearing intermediate process. Therefore, in specific scenarios, we should choose which method to use according to the situation.

For Method 2, we provide another way to write the same function:


var timer=undefined,delay=50; 
function throttle2(method){ 
  if(timer){ 
    return ; 
  } 
  method(); 
  timer=setTimeout(function(){ 
    timer=undefined; 
  },delay); 
} 

Finally, I would like to make a foreign statement to explain the name of function throttling in 1. We often see two method names, throttle and debounce. throttle can be translated as "restraint and jamming", and debounce can be translated as "anti-rebound". In "JavaScript Advanced Programming", the author introduced Method 1, and the author used the function name "throttle". In the third party JavaScript programming, method 1 and method 2 appeared at the same time. The author named method 1 as "debounce" and method 2 as "throttle". When introducing the two methods at the same time in China, some articles mistakenly named Method 1 as "throttle" and Method 2 as "debounce", which is irresponsible from an English perspective. Therefore, bring order out of chaos here: Method 1 is suitable to be understood as "anti-rebound" and should be named "debounce"; Method 2 is suitable to be understood as "function control" and should be named "throttle".

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: