SlideShare a Scribd company logo
1 of 104
Performance em 
javascript
Guilherme Bortolin Serrano 
Bacharel em Desenho Industrial (ULBRA) 
Pós graduado em Gestão Empreendedora (SENAC) 
Empreendedor 
Programador / Hacker
Experiências
OTIMIZAÇÃO
We should forget about small 
efficiencies, say about 97% of the time: 
premature optimization is the root of all 
evil 
" 
Tony Hoare ~1975 
Nós devemos desconsiderar ajustes para pequenas performance, digamos 
que em 97% do tempo a otimização prematura é a raiz de todo o mal
A raiiz de todo o mall!!
Não otimize 
prematuramente
Qual o custo da otimização? 
- Aumento de tempo de desenvolvimento inicial 
- Pode prejudicar a leitura do código: 
- Mais difícil fazer novas implementações 
- Mais difícil dar manutenção no código 
(principalmente em equipe)
Por outro lado...
Pensar cedo em otimização 
- Melhora planejamento para otimizações futuras 
- Evita "surpresas" no lançamento do produto em 
produção
Porque otimizar?
Abandono de página = prejuízo 
https://blog.kissmetrics.com/loading-time/?wide=1
Ganhos reais 
- Experiência do usuário 
- + felicidade 
- + vendas 
- + ROI 
- + pageviews 
- - abandono de página / ação 
- Outros "menos importantes" 
- Economia de banda, redução de custo com servidor...
Mensurando 
performance
"Uso Internet Explorer 
em uma VM" 
@chrisb
JSPerf 
http://jsperf.com/
debug / console
Chrome DEV Tools 
https://developer.chrome.com/devtools/docs/cpu-profiling
Otimizando!
DOM
Evite repaint e reflow 
DOM
Repaint 
O repaint acontece quando mudanças são feitas em elementos que alteram a visualização mas não 
afetam o layout. 
- Outline 
- Visibility 
- Background color 
- etc 
* A Opera diz que o repaint é custoso pois a visibilidade de todos os elementos da árvore do DOM. 
DOM
Reflow 
DOM 
O reflow acontece quando existem mudanças no layout da página (largura, padding, posicionamento) 
e a alteração de um elemento se extende aos childs e aos parents.
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - 
a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos 
childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um 
elemento se
O que causa um reflow? 
Resize da janela 
Alteração de fonte 
Adicionar ou remover uma stylesheet 
Alteração de conteúdos (como o usuário escrever em um input…) 
Ativação de pseudoclass como :hover 
Manipulação do atributo classe 
Manipulação do DOM 
Calcular offsetWidth ou offsetHeight 
Definir um atributo de uma propriedade de estilo 
Praticamente tudo que é legal fazer com JS. 
DOM
<body> 
<div class=”error”> 
<h4>My Module</h4> 
<p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol> 
</div> 
</body> 
DOM
<body> 
<div class=”error”> 
<h4>My Module</h4> 
<p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol> 
</div> 
</body> 
DOM 
reflow
<body> 
<div class=”error”> 
<h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol> 
</div> 
</body> 
DOM 
reflow -> child
<body><div class=”error”> 
<h4>My Module</h4> 
<p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol></div> 
</body> 
DOM 
reflow -> parent
<body><div class=”error”> <h4>My Module</h4> 
<p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol></div> 
</body> 
DOM 
reflow -> child
<body><div class=”error”> <h4>My Module</h4> 
<p><strong>Error:</strong>Description of the error…</p> 
<h5>Corrective action required:</h5> 
<ol> 
<li>Step one</li> 
<li>Step two</li> 
</ol></div> 
</body> 
DOM 
reflow -> child
Uma captura rara 
DOM 
em imagem de um reflow
Reflow 
DOM
Altere o DOM somente 
quando for necessário 
DOM
Evitando manipulação do DOM 
for (var i = 0; i < 100; i++) { 
document.getElementById("teste").innerHTML += "<span>" + i + "</span>"; 
} 
// Manipula o DOM a cada iteração :( 
DOM
Evitando manipulação do DOM 
var myList = ""; 
for (var i = 0; i < 100; i++) { 
myList += "<span>" + i + "</span>"; 
} 
document.getElementById("teste").innerHTML = myList; 
// Concatena uma string e manipula o DOM apenas uma vez :) 
DOM
Evitando cálculo de offset 
var div = document.getElementById("to-measure"), 
lis = document.getElementsByTagName('li'), 
i, len; 
for (i = 0, len = lis.length; i < len; i++) { 
lis[i].style.width = div.offsetWidth + 'px'; 
} 
DOM 
http://jsbin.com/aqavin/2/quiet
Evitando cálculo de offset 
var div = document.getElementById("to-measure"), 
lis = document.getElementsByTagName('li'), 
i, len;for (i = 0, len = lis.length; i < len; i++) { 
lis[i].style.width = div.offsetWidth + 'px'; 
} 
DOM 
http://jsbin.com/aqavin/2/quiet 
reflow, reflow, reflow...
Evitando cálculo de offset 
var div = document.getElementById("to-measure"), 
lis = document.getElementsByTagName('li'), 
widthToSet = div.offsetWidth, 
i, len; 
for (i = 0, len = lis.length; i < len; i++) { 
lis[i].style.width = widthToSet + 'px'; 
} 
DOM 
http://jsbin.com/aqavin/2/quiet
Evitando cálculo de offset 
var div = document.getElementById("to-measure"), 
lis = document.getElementsByTagName('li'), 
widthToSet = div.offsetWidth, 
i, len; 
for (i = 0, len = lis.length; i < len; i++) { 
lis[i].style.width = widthToSet + 'px'; 
} 
DOM 
http://jsbin.com/aqavin/2/quiet 
cache do offsetWidth 
sem reflow :)
TESTE!
Literals 
var arr = []; 
var obj = {}; 
var arr = new Array(); 
var obj = new Object();
Literals 
var arr = []; 
var obj = {}; 
var arr = new Array(); 
var obj = new Object();
Function vs Inline* 
function a(x,y){ 
return x + y; 
} 
a("4", "5"); 
"4" + "5" 
* sempre considere o custo de manutenção / leitura
Function vs Inline* 
a("4", "5"); "4" + "5"
Function vs Inline* 
a("4", "5"); "4" + "5" 
Questione: essa diferença 
compensa manutenção do 
código?
Regular Expression
var texts = [ 
"foo bar foo bar foo bar", 
"foobarfoobarfoobar", 
"foo asdfasdfasdf bar" 
] 
REGEX
var texts = [ 
"foo bar foo bar foo bar", 
"foobarfoobarfoobar", 
"foo asdfasdfasdf bar" 
] 
REGEX 
cache normalmente é uma boa ideia
REGEX
REGEX
exec(); VS match(); VS test(); 
var oRegex = /({:([0-9]):})/; 
var str = "asdf{:1:}jal{:2:}sdk{:3:}fj_8{:4:}kjdk"; 
REGEX
REGEX
Array
for(); 
function indexOfFor(ar,v){ 
for (var i = 0,l=ar.length; i < l; i++) { 
if (ar[i] === v) { 
return i; 
} 
} 
return -1; 
} 
Array
for(); while(); 
function indexOfFor(ar,v){ 
for (var i = 0,l=ar.length; i < l; i++) { 
if (ar[i] === v) { 
return i; 
} 
} 
return -1; 
} 
function indexOfWhile(ar,v){ 
var i=-1, imax = ar.length; 
while (++i < imax) { 
if (ar[i] === v) 
return i; 
} 
return -1; 
} 
Array
for(); while(); indexOf(); 
function indexOfFor(ar,v){ 
for (var i = 0,l=ar.length; i < l; i++) { 
if (ar[i] === v) { 
return i; 
} 
} 
return -1; 
} 
function indexOf(ar,v){ 
return ar.indexOf(v); 
} 
function indexOfWhile(ar,v){ 
var i=-1, imax = ar.length; 
while (++i < imax) { 
if (ar[i] === v) 
return i; 
} 
return -1; 
} 
Array
Array
Como limpar um array? 
Array
Array
Iterações 
for (i = 0; i < arr.length; i++) { 
// calcula o length a cada iteração 
} 
// bad, bad, no donut for you! :( 
Array
Iterações com cache 
for (i = 0; i < arr.length; i++) { 
// calcula o length a cada iteração 
} 
// bad, bad, no donut for you! :( 
for (i = 0, len = arr.length; i < len; i++) { 
// calcula o length uma vez e cacheia 
// a variável "len" 
} 
// :D 
Array
Math
parseInt(); 
parseInt(12.9); 
Math
parseInt(); 
Math.floor(); 
parseInt(12.9); Math.floor(12.9); 
Math
~~ 
Bitwise 
Bitwise 
Bitwise 
Bitwise 
Bitwise 
Math 
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
parseInt(); 
Math.floor(); 
~~ 
parseInt(12.9); 
~~(1 * "12.9"); 
// :(: 
// NOT NOT (coisa estranha, magia negra, etc) 
Math.floor(12.9); 
Math
Math
~~ (NOT NOT) 
var r = 1234567890.99 
~~(r) 
// 1234567890 
var r = 12345678901.99 
~~(r) 
// -539222987 
// ? 
Math
jQuery
A raiiz de todo o mall!!
getElementById(); 
document.getElemntById('teste'); 
jQuery
getElementById(); $('#'); 
document.getElemntById('teste'); $('#teste'); 
jQuery
getElementById(); $('#'); 
document.getElemntById('teste'); 
395x mais rápido! 
$('#teste'); 
jQuery
jQuery
$('.') vs querySelectorjQuery
$('.') vs querySelectorjQuery
$('.') vs querySelectorjQuery 
suporte
$('.') vs querySelectorjQuery 
Mais de 14 vezes mais rápido
.empty() VS .html('') 
.empty(); .html(''); 
jQuery
.empty() VS .html('') 
.empty(); 
2 x mais rápido 
.html(''); 
:( 
jQuery
Ações no seletor 
$('.lorem').class('cached'); 
$('.lorem').html('cached'); 
$('.lorem').click(function(){ 
console.log('click'); 
}); 
jQuery
Ações no seletor - cache 
$('.lorem').class('cached'); 
$('.lorem').html('cached'); 
$('.lorem').click(function(){ 
console.log('click'); 
}); 
// :( 
var el = $('.lorem'); 
el.class('cached'); 
el.html('cached'); 
el.click(function(){ 
console.log('click'); 
}); 
// RAZOÁVEL 
jQuery
Ações no seletor 
chain 
$('.lorem') 
.class('cached') 
.html('cached') 
.click(function(){ 
console.log('click'); 
}); 
jQuery
jQuery
find() 
div>(ul#list>(li.item1+li.item2)) 
div 
ul#list 
li.item1 
li.item2 
ul#list2 
li 
li 
jQuery
find() 
$test1 = $('#list li.test1'); 
$test2 = $('#list li.test2'); 
jQuery
find() 
$test1 = $('#list li.test1'); 
$test2 = $('#list li.test2'); 
$test1 = $('.test1'); 
$test2 = $('.test2'); 
// Se tem classe repetida pode 
perder o sentido / performar pior 
jQuery
find() 
$test1 = $('#list li.test1'); 
$test2 = $('#list li.test2'); 
$list = $('#list'); 
$test1 = $list.find('li.test1'); 
$test2 = $list.find('li.test2'); 
$test1 = $('.test1'); 
$test2 = $('.test2'); 
// Se tem classe repetida pode 
perder o sentido / performar pior 
jQuery
find() 
$test1 = $('#list li.test1'); 
$test2 = $('#list li.test2'); 
$list = $('#list'); 
$test1 = $list.find('li.test1'); 
$test2 = $list.find('li.test2'); 
$test1 = $('.test1'); 
$test2 = $('.test2'); 
// Se tem classe repetida pode 
perder o sentido / performar pior 
$list = $('#list'); 
$test1 = $list.find('.test1'); 
$test2 = $list.find('.test1'); 
jQuery
jQuery 
13x
OBRIGADO! 
@gserrano 
guilherme@gssolutions.com.br 
hacklab.club

More Related Content

Viewers also liked

Developing with pyGTK in EeePC
Developing with pyGTK in EeePCDeveloping with pyGTK in EeePC
Developing with pyGTK in EeePCTsungWei Hu
 
Astronomia con il software libero
Astronomia con il software liberoAstronomia con il software libero
Astronomia con il software liberoStefano Morandi
 
E-commerce (Social Commerce) Infanto-Juvenil
E-commerce (Social Commerce) Infanto-JuvenilE-commerce (Social Commerce) Infanto-Juvenil
E-commerce (Social Commerce) Infanto-JuvenilKari Kotake
 
Responsive design business_case_or_not
Responsive design business_case_or_notResponsive design business_case_or_not
Responsive design business_case_or_notTommi Pelkonen
 
Adrese radio bune
Adrese radio buneAdrese radio bune
Adrese radio buneHadi Acasa
 
Parmigiano e Grana Padano
Parmigiano e Grana PadanoParmigiano e Grana Padano
Parmigiano e Grana Padanoiccorniglio
 
雲端運算的演進與定義
雲端運算的演進與定義雲端運算的演進與定義
雲端運算的演進與定義Awei Hsu
 
Tættere på salgets hellige gral
Tættere på salgets hellige gralTættere på salgets hellige gral
Tættere på salgets hellige gralIBM Danmark
 
The Future of the Web
The Future of the WebThe Future of the Web
The Future of the Webcrassi
 

Viewers also liked (20)

Developing with pyGTK in EeePC
Developing with pyGTK in EeePCDeveloping with pyGTK in EeePC
Developing with pyGTK in EeePC
 
E commerce Programming
E commerce Programming E commerce Programming
E commerce Programming
 
1. lipid
1. lipid1. lipid
1. lipid
 
Evaluacion segunda unidad
Evaluacion segunda unidadEvaluacion segunda unidad
Evaluacion segunda unidad
 
Astronomia con il software libero
Astronomia con il software liberoAstronomia con il software libero
Astronomia con il software libero
 
E-commerce (Social Commerce) Infanto-Juvenil
E-commerce (Social Commerce) Infanto-JuvenilE-commerce (Social Commerce) Infanto-Juvenil
E-commerce (Social Commerce) Infanto-Juvenil
 
Responsive design business_case_or_not
Responsive design business_case_or_notResponsive design business_case_or_not
Responsive design business_case_or_not
 
Speech
SpeechSpeech
Speech
 
Travel cambodia
Travel cambodiaTravel cambodia
Travel cambodia
 
Adrese radio bune
Adrese radio buneAdrese radio bune
Adrese radio bune
 
Parmigiano e Grana Padano
Parmigiano e Grana PadanoParmigiano e Grana Padano
Parmigiano e Grana Padano
 
Training program plan final
Training program plan finalTraining program plan final
Training program plan final
 
Vowel sounds1.1
Vowel sounds1.1Vowel sounds1.1
Vowel sounds1.1
 
Fuck Email
Fuck EmailFuck Email
Fuck Email
 
Revista Dia
Revista Dia Revista Dia
Revista Dia
 
Матющенко И.И. Разработка ООП
Матющенко И.И. Разработка ООПМатющенко И.И. Разработка ООП
Матющенко И.И. Разработка ООП
 
雲端運算的演進與定義
雲端運算的演進與定義雲端運算的演進與定義
雲端運算的演進與定義
 
Tættere på salgets hellige gral
Tættere på salgets hellige gralTættere på salgets hellige gral
Tættere på salgets hellige gral
 
Apresentação1
Apresentação1Apresentação1
Apresentação1
 
The Future of the Web
The Future of the WebThe Future of the Web
The Future of the Web
 

Similar to Performance em javascript

Modelando aplicação em documento - MongoDB
Modelando aplicação em documento - MongoDBModelando aplicação em documento - MongoDB
Modelando aplicação em documento - MongoDBThiago Avelino
 
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...MIRA - Um framework Javascript para construção de interfaces adaptativas em a...
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...Ezequiel Bertti
 
Desenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana frameworkDesenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana frameworkMarcelo Rodrigo
 
II Oficina de Webdesign - Lecom
II Oficina de Webdesign - LecomII Oficina de Webdesign - Lecom
II Oficina de Webdesign - Lecommugga
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Rodrigo Urubatan
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontMichel Ribeiro
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoFreedom DayMS
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkPablo Dall'Oglio
 
Desenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certaDesenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certaNelson Glauber Leal
 
Como Perder Peso (no browser)
Como Perder Peso (no browser)Como Perder Peso (no browser)
Como Perder Peso (no browser)Zeno Rocha
 
O que todos os developers devem saber sobre seo
O que todos os developers devem saber sobre seoO que todos os developers devem saber sobre seo
O que todos os developers devem saber sobre seointrofini
 
Da argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguroDa argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguroMichael Castillo Granados
 
O que você faz para ser Mobile? TDC2013
O que você faz para ser Mobile? TDC2013O que você faz para ser Mobile? TDC2013
O que você faz para ser Mobile? TDC2013Jackson F. de A. Mafra
 

Similar to Performance em javascript (20)

Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
Modelando aplicação em documento - MongoDB
Modelando aplicação em documento - MongoDBModelando aplicação em documento - MongoDB
Modelando aplicação em documento - MongoDB
 
Zend Framework
Zend FrameworkZend Framework
Zend Framework
 
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...MIRA - Um framework Javascript para construção de interfaces adaptativas em a...
MIRA - Um framework Javascript para construção de interfaces adaptativas em a...
 
Html5 workshop
Html5 workshopHtml5 workshop
Html5 workshop
 
Desenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana frameworkDesenvolvimento ágil com Kohana framework
Desenvolvimento ágil com Kohana framework
 
II Oficina de Webdesign - Lecom
II Oficina de Webdesign - LecomII Oficina de Webdesign - Lecom
II Oficina de Webdesign - Lecom
 
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015Interfaces ricas com Rails e React.JS @ Rubyconf 2015
Interfaces ricas com Rails e React.JS @ Rubyconf 2015
 
Evento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de FrontEvento Front End SP - Arquitetura de Front
Evento Front End SP - Arquitetura de Front
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
 
Programando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um FrameworkProgramando para programadores: Desafios na evolução de um Framework
Programando para programadores: Desafios na evolução de um Framework
 
Desenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certaDesenvolvimento Android: Faça da maneira certa
Desenvolvimento Android: Faça da maneira certa
 
Como Perder Peso (no browser)
Como Perder Peso (no browser)Como Perder Peso (no browser)
Como Perder Peso (no browser)
 
O que todos os developers devem saber sobre seo
O que todos os developers devem saber sobre seoO que todos os developers devem saber sobre seo
O que todos os developers devem saber sobre seo
 
Seo e HTML5
Seo e HTML5Seo e HTML5
Seo e HTML5
 
Da argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguroDa argila ao forte: como desenvolver uma loja com PagSeguro
Da argila ao forte: como desenvolver uma loja com PagSeguro
 
Introdução ao JQuery e AJAX
Introdução ao JQuery e AJAXIntrodução ao JQuery e AJAX
Introdução ao JQuery e AJAX
 
Vue.js
Vue.jsVue.js
Vue.js
 
O que você faz para ser Mobile? TDC2013
O que você faz para ser Mobile? TDC2013O que você faz para ser Mobile? TDC2013
O que você faz para ser Mobile? TDC2013
 
HTML5 Hands On
HTML5 Hands OnHTML5 Hands On
HTML5 Hands On
 

More from Guilherme Serrano

ROI no front end - vamos pensar em lucro?
ROI no front end - vamos pensar em lucro?ROI no front end - vamos pensar em lucro?
ROI no front end - vamos pensar em lucro?Guilherme Serrano
 
Empreendedorismo sem maquiagem
Empreendedorismo sem maquiagemEmpreendedorismo sem maquiagem
Empreendedorismo sem maquiagemGuilherme Serrano
 
Componetização de CSS com o Compass (Front in Sampa 2013)
Componetização de CSS com o Compass (Front in Sampa 2013)Componetização de CSS com o Compass (Front in Sampa 2013)
Componetização de CSS com o Compass (Front in Sampa 2013)Guilherme Serrano
 

More from Guilherme Serrano (6)

ROI no front end - vamos pensar em lucro?
ROI no front end - vamos pensar em lucro?ROI no front end - vamos pensar em lucro?
ROI no front end - vamos pensar em lucro?
 
Empreendedorismo sem maquiagem
Empreendedorismo sem maquiagemEmpreendedorismo sem maquiagem
Empreendedorismo sem maquiagem
 
Componetização de CSS com o Compass (Front in Sampa 2013)
Componetização de CSS com o Compass (Front in Sampa 2013)Componetização de CSS com o Compass (Front in Sampa 2013)
Componetização de CSS com o Compass (Front in Sampa 2013)
 
Responsive design
Responsive designResponsive design
Responsive design
 
Usabilidade na web
Usabilidade na webUsabilidade na web
Usabilidade na web
 
Análise Heuristica
Análise HeuristicaAnálise Heuristica
Análise Heuristica
 

Performance em javascript

  • 2. Guilherme Bortolin Serrano Bacharel em Desenho Industrial (ULBRA) Pós graduado em Gestão Empreendedora (SENAC) Empreendedor Programador / Hacker
  • 3.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 14. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil " Tony Hoare ~1975 Nós devemos desconsiderar ajustes para pequenas performance, digamos que em 97% do tempo a otimização prematura é a raiz de todo o mal
  • 15. A raiiz de todo o mall!!
  • 17. Qual o custo da otimização? - Aumento de tempo de desenvolvimento inicial - Pode prejudicar a leitura do código: - Mais difícil fazer novas implementações - Mais difícil dar manutenção no código (principalmente em equipe)
  • 19. Pensar cedo em otimização - Melhora planejamento para otimizações futuras - Evita "surpresas" no lançamento do produto em produção
  • 21. Abandono de página = prejuízo https://blog.kissmetrics.com/loading-time/?wide=1
  • 22. Ganhos reais - Experiência do usuário - + felicidade - + vendas - + ROI - + pageviews - - abandono de página / ação - Outros "menos importantes" - Economia de banda, redução de custo com servidor...
  • 24. "Uso Internet Explorer em uma VM" @chrisb
  • 27. Chrome DEV Tools https://developer.chrome.com/devtools/docs/cpu-profiling
  • 29.
  • 30. DOM
  • 31. Evite repaint e reflow DOM
  • 32. Repaint O repaint acontece quando mudanças são feitas em elementos que alteram a visualização mas não afetam o layout. - Outline - Visibility - Background color - etc * A Opera diz que o repaint é custoso pois a visibilidade de todos os elementos da árvore do DOM. DOM
  • 33. Reflow DOM O reflow acontece quando existem mudanças no layout da página (largura, padding, posicionamento) e a alteração de um elemento se extende aos childs e aos parents.
  • 34. a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se extende aos childs e aos parents - a alteração de um elemento se
  • 35. O que causa um reflow? Resize da janela Alteração de fonte Adicionar ou remover uma stylesheet Alteração de conteúdos (como o usuário escrever em um input…) Ativação de pseudoclass como :hover Manipulação do atributo classe Manipulação do DOM Calcular offsetWidth ou offsetHeight Definir um atributo de uma propriedade de estilo Praticamente tudo que é legal fazer com JS. DOM
  • 36. <body> <div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol> </div> </body> DOM
  • 37. <body> <div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol> </div> </body> DOM reflow
  • 38. <body> <div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol> </div> </body> DOM reflow -> child
  • 39. <body><div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol></div> </body> DOM reflow -> parent
  • 40. <body><div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol></div> </body> DOM reflow -> child
  • 41. <body><div class=”error”> <h4>My Module</h4> <p><strong>Error:</strong>Description of the error…</p> <h5>Corrective action required:</h5> <ol> <li>Step one</li> <li>Step two</li> </ol></div> </body> DOM reflow -> child
  • 42. Uma captura rara DOM em imagem de um reflow
  • 43.
  • 45. Altere o DOM somente quando for necessário DOM
  • 46. Evitando manipulação do DOM for (var i = 0; i < 100; i++) { document.getElementById("teste").innerHTML += "<span>" + i + "</span>"; } // Manipula o DOM a cada iteração :( DOM
  • 47. Evitando manipulação do DOM var myList = ""; for (var i = 0; i < 100; i++) { myList += "<span>" + i + "</span>"; } document.getElementById("teste").innerHTML = myList; // Concatena uma string e manipula o DOM apenas uma vez :) DOM
  • 48. Evitando cálculo de offset var div = document.getElementById("to-measure"), lis = document.getElementsByTagName('li'), i, len; for (i = 0, len = lis.length; i < len; i++) { lis[i].style.width = div.offsetWidth + 'px'; } DOM http://jsbin.com/aqavin/2/quiet
  • 49. Evitando cálculo de offset var div = document.getElementById("to-measure"), lis = document.getElementsByTagName('li'), i, len;for (i = 0, len = lis.length; i < len; i++) { lis[i].style.width = div.offsetWidth + 'px'; } DOM http://jsbin.com/aqavin/2/quiet reflow, reflow, reflow...
  • 50. Evitando cálculo de offset var div = document.getElementById("to-measure"), lis = document.getElementsByTagName('li'), widthToSet = div.offsetWidth, i, len; for (i = 0, len = lis.length; i < len; i++) { lis[i].style.width = widthToSet + 'px'; } DOM http://jsbin.com/aqavin/2/quiet
  • 51. Evitando cálculo de offset var div = document.getElementById("to-measure"), lis = document.getElementsByTagName('li'), widthToSet = div.offsetWidth, i, len; for (i = 0, len = lis.length; i < len; i++) { lis[i].style.width = widthToSet + 'px'; } DOM http://jsbin.com/aqavin/2/quiet cache do offsetWidth sem reflow :)
  • 53. Literals var arr = []; var obj = {}; var arr = new Array(); var obj = new Object();
  • 54. Literals var arr = []; var obj = {}; var arr = new Array(); var obj = new Object();
  • 55. Function vs Inline* function a(x,y){ return x + y; } a("4", "5"); "4" + "5" * sempre considere o custo de manutenção / leitura
  • 56. Function vs Inline* a("4", "5"); "4" + "5"
  • 57. Function vs Inline* a("4", "5"); "4" + "5" Questione: essa diferença compensa manutenção do código?
  • 59. var texts = [ "foo bar foo bar foo bar", "foobarfoobarfoobar", "foo asdfasdfasdf bar" ] REGEX
  • 60. var texts = [ "foo bar foo bar foo bar", "foobarfoobarfoobar", "foo asdfasdfasdf bar" ] REGEX cache normalmente é uma boa ideia
  • 61. REGEX
  • 62. REGEX
  • 63. exec(); VS match(); VS test(); var oRegex = /({:([0-9]):})/; var str = "asdf{:1:}jal{:2:}sdk{:3:}fj_8{:4:}kjdk"; REGEX
  • 64. REGEX
  • 65. Array
  • 66. for(); function indexOfFor(ar,v){ for (var i = 0,l=ar.length; i < l; i++) { if (ar[i] === v) { return i; } } return -1; } Array
  • 67. for(); while(); function indexOfFor(ar,v){ for (var i = 0,l=ar.length; i < l; i++) { if (ar[i] === v) { return i; } } return -1; } function indexOfWhile(ar,v){ var i=-1, imax = ar.length; while (++i < imax) { if (ar[i] === v) return i; } return -1; } Array
  • 68. for(); while(); indexOf(); function indexOfFor(ar,v){ for (var i = 0,l=ar.length; i < l; i++) { if (ar[i] === v) { return i; } } return -1; } function indexOf(ar,v){ return ar.indexOf(v); } function indexOfWhile(ar,v){ var i=-1, imax = ar.length; while (++i < imax) { if (ar[i] === v) return i; } return -1; } Array
  • 69. Array
  • 70. Como limpar um array? Array
  • 71. Array
  • 72. Iterações for (i = 0; i < arr.length; i++) { // calcula o length a cada iteração } // bad, bad, no donut for you! :( Array
  • 73. Iterações com cache for (i = 0; i < arr.length; i++) { // calcula o length a cada iteração } // bad, bad, no donut for you! :( for (i = 0, len = arr.length; i < len; i++) { // calcula o length uma vez e cacheia // a variável "len" } // :D Array
  • 74. Math
  • 77. ~~ Bitwise Bitwise Bitwise Bitwise Bitwise Math https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
  • 78.
  • 79. parseInt(); Math.floor(); ~~ parseInt(12.9); ~~(1 * "12.9"); // :(: // NOT NOT (coisa estranha, magia negra, etc) Math.floor(12.9); Math
  • 80. Math
  • 81. ~~ (NOT NOT) var r = 1234567890.99 ~~(r) // 1234567890 var r = 12345678901.99 ~~(r) // -539222987 // ? Math
  • 83. A raiiz de todo o mall!!
  • 86. getElementById(); $('#'); document.getElemntById('teste'); 395x mais rápido! $('#teste'); jQuery
  • 91. $('.') vs querySelectorjQuery Mais de 14 vezes mais rápido
  • 92. .empty() VS .html('') .empty(); .html(''); jQuery
  • 93. .empty() VS .html('') .empty(); 2 x mais rápido .html(''); :( jQuery
  • 94. Ações no seletor $('.lorem').class('cached'); $('.lorem').html('cached'); $('.lorem').click(function(){ console.log('click'); }); jQuery
  • 95. Ações no seletor - cache $('.lorem').class('cached'); $('.lorem').html('cached'); $('.lorem').click(function(){ console.log('click'); }); // :( var el = $('.lorem'); el.class('cached'); el.html('cached'); el.click(function(){ console.log('click'); }); // RAZOÁVEL jQuery
  • 96. Ações no seletor chain $('.lorem') .class('cached') .html('cached') .click(function(){ console.log('click'); }); jQuery
  • 98. find() div>(ul#list>(li.item1+li.item2)) div ul#list li.item1 li.item2 ul#list2 li li jQuery
  • 99. find() $test1 = $('#list li.test1'); $test2 = $('#list li.test2'); jQuery
  • 100. find() $test1 = $('#list li.test1'); $test2 = $('#list li.test2'); $test1 = $('.test1'); $test2 = $('.test2'); // Se tem classe repetida pode perder o sentido / performar pior jQuery
  • 101. find() $test1 = $('#list li.test1'); $test2 = $('#list li.test2'); $list = $('#list'); $test1 = $list.find('li.test1'); $test2 = $list.find('li.test2'); $test1 = $('.test1'); $test2 = $('.test2'); // Se tem classe repetida pode perder o sentido / performar pior jQuery
  • 102. find() $test1 = $('#list li.test1'); $test2 = $('#list li.test2'); $list = $('#list'); $test1 = $list.find('li.test1'); $test2 = $list.find('li.test2'); $test1 = $('.test1'); $test2 = $('.test2'); // Se tem classe repetida pode perder o sentido / performar pior $list = $('#list'); $test1 = $list.find('.test1'); $test2 = $list.find('.test1'); jQuery