Download - Throttle and Debounce Patterns in Web Apps
PATTERNS IN WEB APPS
THROTTLE &
DEBOUNCE
@ALMIRFILHO
@almirfilho
@loopinfinito
l8p.com.br
@almirfilho
@loopinfinito
l8p.com.br
@almirfilho
@loopinfinito
l8p.com.br
after conf
THE PROBLEM
How to control user events frequency?
onclick onresize onscroll onmousemove
SOME CASES
onclickOrder some shit
Some AJAX action. Whatever
…
onclickOrder some shit
Some AJAX action. Whatever
click
freak
onresizeResponsive modafoca
onresize
∆ = 100px
triggerings! !%?#$
≃ 100 *
Responsive modafoca
onscrollParalax bullshit
onscroll
∆ = 100px… same fuc*ing
thing
≃
Paralax bullshit
onmousemoveGaming junk
onmousemove
∆x = 100px ∆y = 50px
trigg… OMG plz stop
≃ 150 *
Gaming junk
**BONUS** PROBLEM
Updating <canvas> drawings?
just redraw E-V-E -R -Y-T-H- I -N-G
Updating <canvas> drawings?
stage.update = function(){ redrawHeavyShit(); }; !
while(game.isOn){ game.step(); stage.update(); }
stupid game loop
stage.update = function(){ redrawHeavyShit(); }; !var gameLoop = function(){ game.step(); stage.update(); requestAnimationFrame(gameLoop); }; !gameLoop();
WAY COOLER
stage.update = function(){ redrawHeavyShit(); }; !var gameLoop = function(){ game.step(); stage.update(); requestAnimationFrame(gameLoop); }; !gameLoop();
WAY COOLER
Measuring damage with
dev tools
RENDERING & PAINTING COSTS
all major and modern* browsers * even in IE (11)
So, how to control user events frequency?
THROTTLE
A throttle is a mechanism to
manage fuel flow in an engine
ENGINE THROTTLE
So, throttle is just a valve?
!yeeep
resizing scrolling
mouse moving
COMMON CASES
tE E E E E E E E E E E
onscroll
paralax()
0.1s0s
tE E E E E E E E E E E
onscroll throttled
paralax()
0.1s0s
THROTTLE
tE E E E E E E E E E E
onscroll throttled
paralax()
0.1s0s
THROTTLE
var paralax = function(args){ complexHeavyShit(); }; !
window.addEventListener(‘scroll’, function(e){ paralax(e.args); });
var paralax = function(args){ complexHeavyShit(); }; !
window.addEventListener(‘scroll’, throttleParalax() );
LET’S THROOOOTLE IT
var throttleParalax = (function(){ var timeWindow = 500; var now = (new Date()).getTime(); var lastExecution = new Date(now - timeWindow); ! var paralax = function(args){ complexHeavyShit(); }; ! return function(){ var now = (new Date()).getTime(); if(lastExecution.getTime() + timeWindow <= now){ lastExecution = new Date(); return paralax.apply(this, arguments); } }; }());
var throttleParalax = (function(){ var timeWindow = 500; var now = (new Date()).getTime(); var lastExecution = new Date(now - timeWindow); ! var paralax = function(args){ complexHeavyShit(); }; ! return function(){ var now = (new Date()).getTime(); if(lastExecution.getTime() + timeWindow <= now){ lastExecution = new Date(); return paralax.apply(this, arguments); } }; }());
sets
a context
var throttleParalax = (function(){ var timeWindow = 500; var now = (new Date()).getTime(); var lastExecution = new Date(now - timeWindow); ! var paralax = function(args){ complexHeavyShit(); }; ! return function(){ var now = (new Date()).getTime(); if(lastExecution.getTime() + timeWindow <= now){ lastExecution = new Date(); return paralax.apply(this, arguments); } }; }());
sets the func.
var throttleParalax = (function(){ var timeWindow = 500; var now = (new Date()).getTime(); var lastExecution = new Date(now - timeWindow); ! var paralax = function(args){ complexHeavyShit(); }; ! return function(){ var now = (new Date()).getTime(); if(lastExecution.getTime() + timeWindow <= now){ lastExecution = new Date(); return paralax.apply(this, arguments); } }; }());
returns the event handler
Let’s visualize it
tE
500ms0s
event
happens
Let’s visualize it
t
500ms0s
E
Let’s visualize it
event executes
t
500ms0s
100msE
timeWindow
Let’s visualize it
t
500ms0s
100msE
Let’s visualize it
another event
happens
E
t
500ms0s
100msE
Let’s visualize it
no execution
E
t
500ms0s
100msE
Let’s visualize it
event
happens
E E
t
500ms0s
100msE
Let’s visualize it
same thing
now
E E
t
500ms0s
100msE
Let’s visualize itE 100msE
t
500ms0s
100msE
Let’s visualize itE 100msE E E E
DEBOUNCE
A debouncing is a technique to
guarantee that a button was pressed
only once.
ELECTRONIC DEBOUNCING
Debounce cancels multiple actions for postpone to the
last one.
clicking key pressing
COMMON CASES
tE E E E E E E E E
onkeyup
autoComplete()
1s0s
tE E E E E E E E E
onkeyup debouncing1s0s
DEBOUNCE
autoComplete()
tE E E E E E E E E
onkeyup debouncing1s0s
DEBOUNCE
autoComplete()
btn.addEventListener(‘keyup’, function(){ autoComplete(); });
btn.addEventListener(‘keyup’, debounceAutoComplete() );
LET’S DEBOOOUNCE IT
var debounceAutoComplete = (function(){ var timeWindow = 100; var timeout; ! var autoComplete = function(arg1, arg2){/* … */}; ! return function(){ var context = this; var args = arguments; clearTimeout(timeout); timeout = setTimeout(function(){ autoComplete.apply(context, args); }, timeWindow); }; }());
var debounceAutoComplete = (function(){ var timeWindow = 100; var timeout; ! var autoComplete = function(arg1, arg2){/* … */}; ! return function(){ var context = this; var args = arguments; clearTimeout(timeout); timeout = setTimeout(function(){ autoComplete.apply(context, args); }, timeWindow); }; }());
sets a context
var debounceAutoComplete = (function(){ var timeWindow = 100; var timeout; ! var autoComplete = function(arg1, arg2){/* … */}; ! return function(){ var context = this; var args = arguments; clearTimeout(timeout); timeout = setTimeout(function(){ autoComplete.apply(context, args); }, timeWindow); }; }());
sets the func.
var debounceAutoComplete = (function(){ var timeWindow = 100; var timeout; ! var autoComplete = function(arg1, arg2){/* … */}; ! return function(){ var context = this; var args = arguments; clearTimeout(timeout); timeout = setTimeout(function(){ autoComplete.apply(context, args); }, timeWindow); }; }());
return the
handler
Let’s visualize it
tE
500ms0s
event
happens
Let’s visualize it
t
500ms0s
100msE
setTimeOut
Let’s visualize it
t
500ms0s
100msE
another event
happens
E
Let’s visualize it
t
500ms0s
100msE
clearTimeOut
E
Let’s visualize it
t
500ms0s
100msE
reset
timeOut
E
Let’s visualize it
t
500ms0s
100msE E E
Let’s visualize it
t
500ms0s
100msE E E
Let’s visualize it
t
500ms0s
100msE E E
Let’s visualize it
t
500ms0s
100msE E E
cool to execute!
Let’s visualize it
t
500ms0s
100msE E E
life goes on…
E
Let’s visualize it
READ ABOUT [PT-BR]
but… <x-mimimi>
$(window).scroll($.throttle(250, paralax)); !
$('input').keyup($.debounce(250, autoComplete));
JQUERY PLUGINjquery-throttle-debounce
github.com/cowboy/jquery-throttle-debounce
UNDERSCORE.JS
underscorejs.org
$(window).scroll(_.throttle(paralax, 250)); !
$(‘input’).keyup(_.debounce(autoComplete, 250));
THANK YOU!
@ALMIRFILHO