Upload
almir-filho
View
216
Download
1
Embed Size (px)
DESCRIPTION
A brief discussion on the Throttle and Debounce Patterns. Where, when and why to use them? They solve some problems that may harm the performance of an entire web app due to misuse of user events.
Citation preview
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