performance em javascript

Post on 14-Dec-2014

425 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

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

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

OBRIGADO!

@gserranoguilherme@gssolutions.com.br

hacklab.club

top related