JavaScript anti shake and throttling notes

JavaScript anti shake and throttling

concept

debounce and throttle are two similar but essentially different concepts, but both concepts exist to control the maximum number of executions of a function in a certain period of time. This is particularly important when, for example, binding the onScroll event of function execution. Too many events lead to the backlog of callback functions in the task queue, and the call stack is blocked due to the long execution time of callback functions, which is easy to cause the front-end performance bottleneck. onScroll events will occur 30-100 times when dragging the scroll bar or sliding on the mobile page. At this time, if there are functions that slightly affect the performance in the callback function, This effect will be magnified many times. At this time, anti shake and throttling treatment are particularly important.

Anti shake Debounce

Debounce is the operation of combining multiple calls for a certain period of time or between two specific events into one call. If there is no call within the specified time, the previous multiple consecutive calls will be combined into one execution.

Each vertical line is divided into a time unit, colored as an event in the time unit. The upper part is the occurrence before event processing, and the lower part is the situation after anti shake processing. It can be seen that the anti shake processing synthesizes multiple consecutive events that have occurred into one event after the event stops executing continuously for a certain period of time.

Leading Edge anti shake

Leading Edge anti shake (Leading Edge or Immediate) is an improvement that puts the occurrence of anti shake event at the beginning of the event. When an event occurs, the Leading Edge anti shake will immediately release a corresponding event, and the subsequent continuously released events will be filtered by the Leading Edge anti shake until the event occurs again after the event occurrence interval is greater than the set time, and the throttling function will process the event in the same way.

It can be seen that the leading edge anti shake will be executed immediately when the event occurs, and then the leading edge anti shake operation will be carried out.

Realization of anti shake

The JavaScript library Lodash contains debounce(function, [wait=0], [options = {}]) function can realize anti shake. Function is the function that needs anti shake. Wait is the optional delay milliseconds, option Leading flag Yes (true) no (false) uses leading edge anti shake. This value defaults to false, option Whether the tracking flag uses the default anti shake. This value defaults to true, options Maxwait flag function maximum delay time.

_.debounce(sendEmail, 400, {
    leading: true,
    trailing: false, 
	maxWait: 1000
})

Practical examples

// Avoid expensive computing overhead when the window changes.
$(window).on('resize', _.debounce(calculateLayout, 150));
 
// When clicked, 'sendMail' is then called.
$(element).on('click', _.debounce(sendMail, 300, {
  'leading': true,
  'trailing': false
}));
 
// Ensure that the 'batchLog' will be triggered within 1 second after being called once.
var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
var source = new EventSource('/stream');
$(source).on('message', debounced);
 
// Cancel the anti jitter call of a trailing
$(window).on('popstate', debounced.cancel);

// The left div will print every time the browser issues resize, and the right div will print when no resize event is issued within 400ms
$(document).ready(function(){
  var $win = $(window);
  var $left_panel = $('.left-panel');
  var $right_panel = $('.right-panel');
  
  function display_info($div) {
    $div.append($win.width() + ' x ' + $win.height() +  '<br>');
  }
    
  $(window).on('resize', function(){
    display_info($left_panel);
  });
  
  $(window).on('resize', _.debounce(function() {
    display_info($right_panel);
  }, 400));
});

Method to install only the debounce and throttle functions of Lodash

npm i -g lodash-cli
lodash include = debounce, throttle

Throttle

The purpose of throttling is to allow a method to be executed only once in a certain period of time, which is different from dividing the continuous call segment between the specified anti shake interval and executing the method once before or after this segment. The effect is that throttling will ensure that the function will be executed within a certain period of time, while anti shake will prevent a method from being executed once as long as it is continuous for a specified time.

On the waterfall flow page, the code needs to regularly check the distance between the current scrolling position and the bottom of the page. Throttling will allow this operation, while anti shake will only detect after the user stops scrolling, and the experience is poor.

$(document).ready(function(){
  
  // Check every 300ms the scroll position
  $(document).on('scroll', _.throttle(function(){
    check_if_needs_more_content();
  }, 300));

  function check_if_needs_more_content() {     
    pixelsFromWindowBottomToBottom = 0 + $(document).height() - $(window).scrollTop() -$(window).height();
    
  // console.log($(document).height());
  // console.log($(window).scrollTop());
  // console.log($(window).height());
  // console.log(pixelsFromWindowBottomToBottom);
      
    if (pixelsFromWindowBottomToBottom < 200){
      // Here it would go an ajax request
      $('body').append($('.item').clone());   
    }
  }
});

rAF requestAnimationFrame

Another way to realize the execution rate limit is to use requestAnimationFrame, which binds each frame rendered by the browser interface of 60fps. Its effect is the same as The effect of throttle(function, 16) is similar, but its reliability and performance are better, because it is a micro task and a browser native API. This function is preferred when scrolling, mouse and keyboard events are combined to adjust the position or size of elements and animation.

The disadvantage of rAF mainly comes from that IE9, Opera Mini and some old Android browsers do not support this function, and Nodejs does not support this function

summary

  • Anti shake debounce: synthesize a continuous number of calls into one. It will be executed after default, and the leading edge anti shake will be executed immediately
  • Throttling throttle: it is guaranteed to execute at least one call in each period of time, which can be used for inspection, user operation, etc
  • rAF: a higher performance alternative to throttling, which is best used for UI related tasks, but does not support IE9

Tags: Javascript Front-end

Posted by s0c0 on Sat, 07 May 2022 13:14:25 +0300