JavaScript Mini-curso de introdução a JavaScript Promoção: PET-SI Slides em : //.
Performance em javascript
-
Upload
guilherme-serrano -
Category
Technology
-
view
425 -
download
1
description
Transcript of Performance em javascript
Performance em javascript
Guilherme Bortolin Serrano
Bacharel em Desenho Industrial (ULBRA)Pós graduado em Gestão Empreendedora (SENAC)EmpreendedorProgramador / 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 raiz de todo o mal!
A raiz de todo o mal!
Não otimizeprematuramente
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?
https://blog.kissmetrics.com/loading-time/?wide=1
Abandono de página = prejuízo
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...
Mensurandoperformance
"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
RepaintO 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
ReflowO 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.
DOM
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 janelaAlteração de fonteAdicionar ou remover uma stylesheetAlteração de conteúdos (como o usuário escrever em um input…)Ativação de pseudoclass como :hoverManipulação do atributo classeManipulação do DOMCalcular offsetWidth ou offsetHeightDefinir 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>
DOMreflow
<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>
DOMreflow -> 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>
DOMreflow -> 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>
DOMreflow -> 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>
DOMreflow -> child
Uma captura raraem imagem de um
reflow
DOM
ReflowDOM
Altere o DOM somente
quando for necessário
DOM
Evitando manipulação do DOMfor (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 DOMvar 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 offsetvar 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 offsetvar 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 offsetvar 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 offsetvar 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çõesfor (i = 0; i < arr.length; i++) { // calcula o length a cada iteração}
// bad, bad, no donut for you! :(
Array
Iterações com cachefor (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
BitwiseBitwise
BitwiseBitwise
Bitwise
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
~~
Math
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 raiz de todo o mal!
A raiz de todo o mal!
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 seletorchain
$('.lorem') .class('cached') .html('cached') .click(function(){ console.log('click'); });
jQuery
jQuery
find()div>(ul#list>(li.item1+li.item2))
divul#list
li.item1li.item2
ul#list2lili
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()
$list = $('#list');$test1 = $list.find('li.test1');$test2 = $list.find('li.test2');
$test1 = $('#list li.test1');$test2 = $('#list li.test2');
$test1 = $('.test1');$test2 = $('.test2');
// Se tem classe repetida pode perder o sentido / performar pior
jQuery
find()
$list = $('#list');$test1 = $list.find('li.test1');$test2 = $list.find('li.test2');
$test1 = $('#list li.test1');$test2 = $('#list 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