Using Throttle and Debounce for Complex Interactions

jQuery Boston Meetup - April 2012

Brian Del Vecchio <bdv@hybernaut.com>

@Hybernaut

Digital Lumens

jQuery UI Event Hooks

Event hooks make things exciting!

Hello Slider

But what if your update event is really slow?

Hello Slider

Easy: Asynchronous Event Handlers!

$('#slider3').slider({
  min: 1, max: 10, step: 0.5, value: 2,
  slide: function(event, ui){
    setTimeout(function(){
      waste(600);
      $('#squeezeme3').css({fontSize: ui.value + "em"});
    }, 1);
  }
});
    
SetTimeout(1)

Throttle: called only once per time interval

$('#slider4').slider({
  min: 1, max: 10, step: 0.5, value: 2,
  slide: _.throttle( function(event, ui){
    waste(600);
    $('#squeezeme4').css({fontSize: ui.value + "em"});
  }, 200)
});
    
throttle(200)

Debounce: called after input stops

$('#slider5').slider({
  min: 1, max: 10, step: 0.5, value: 2,
  slide: _.debounce( function(event, ui){
    waste(600);
    $('#squeezeme5').css({fontSize: ui.value + "em"});
  }, 100)
});
    
debounce(100)

A jQuery debounce using Deferred

$.debounce = function(delay) {
  var lastd = $.Deferred();
  return function() {
    var args = arguments;
    lastd.reject();
    var d = lastd = $.Deferred();
    args = arguments;
    setTimeout(function() {
      return d.resolveWith(context, args);
    }, delay || 100);
    return d.promise();
  };
};
    
Based on https://gist.github.com/1795807 from hitode99

Using the jQuery debounce

$('#slider6').slider({
  min: 1, max: 10, step: 0.5, value: 2,
  slide: $.debounce(this, function(event, ui){
    console.log("jqDeb: ", event, ui);
    waste(600);
    $('#squeezeme6').css({fontSize: ui.value + "em"});
  }, 100)
});
    
$.debounce(100)

Further Reading

  1. Underscore.js debounce
    http://documentcloud.github.com/underscore/#debounce
  2. jQuery throttle / debounce: Sometimes, less is more!
    http://benalman.com/projects/jquery-throttle-debounce-plugin

Use arrow keys to navigate