Aprenda como mensurar e executar testes de performance no Javascript.
Quais são as boas práticas para performance no javascript e como escrever código para ter aplicações mais velozes no client-side?
Algumas dicas para mensurar, exemplos sobre reflow e repaint e testes de performance de operações básicas, iterações, arrays, regex, seletores e também da biblioteca jQuery.
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
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)
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...
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
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 :)
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