O documento fornece dicas para melhorar o desempenho de scripts JavaScript, incluindo posicionar scripts no final do body, agrupar e minificar scripts, acessar variáveis locais em vez de arrays e objetos, e otimizar loops, delegação de eventos e acesso ao DOM.
2. Posicionamento de
Scripts
• Cada <script> bloqueia o render da página
até acabar o seu download
• Tags <script> devem ser colocadas o mais
abaixo possível na página, antes de ser
fechado o </body>
Tuesday, May 4, 2010
3. Agrupar Scripts
• Os Scripts devem ser minificados e
agrupados, melhorando o tempo de
download e libertando slots de pedidos
HTTP
Tuesday, May 4, 2010
5. Acesso a Dados
• Valores literais (null, undefined, ...)
• Variáveis (var x = “teste”)
• Arrays (var arr=[1, 2, “três”])
• Object Members (var obj = {chave: “valor”})
Tuesday, May 4, 2010
6. Acesso a Dados
• Regra geral, o tempo de acesso a variáveis
locais e valores literais é bastante
menor do que o tempo de acesso a arrays
e objectos.
Tuesday, May 4, 2010
7. Acesso a Dados
• Variáveis locais e literais devem ser
utilizados sempre que possível em vez de
arrays ou objectos.
Tuesday, May 4, 2010
8. Scope Chain
• Cada função tem uma propriedade interna
( [[Scope]])
• Contém uma colecção de objectos que
representa o scope no qual a função foi
criada.
• Determina os dados a que a função pode
aceder
Tuesday, May 4, 2010
9. Scope Chain
• Quando a função é criada, herda todas as
variáveis presentes na Scope Global
• Cada chamada a uma função cria um
“Execution Context”, que define o ambiente
em que a função é executada
Tuesday, May 4, 2010
10. Scope Chain
• É criado um “Activation Object”, que
contém entradas para todas as variáveis,
argumentos (e a colecção arguments) e a
variável this.
• Este Activation Object é adicionado à Scope
Chain, à frente do objecto Global.
Tuesday, May 4, 2010
11. Scope Chain
• Quando uma variável é acedida, o motor
procura-a por toda a Scope Chain,
começando pelo objecto mais à frente na
cadeia.
• Quanto mais longe na cadeia estiver a
variável pretendida, mais impacto tem na
performance.
Tuesday, May 4, 2010
12. Scope Chain
• É aconselhável armazenar todos os objectos
fora do Activation Object da função,
reduzindo o impacto na performance.
storing_in_locals.js
Tuesday, May 4, 2010
13. Closures
• Uma função dentro de outra função cria
uma closure.
• Quando a primeira função acaba de
executar, o seu Activation Object não
morre, e continua acessível à função em
closure.
closures.js
Tuesday, May 4, 2010
14. Object Members
• Quanto mais longe na Prototype Chain um
membro estiver, mais custa aceder-lhe.
• Fazer cache de valores em Object Members!
objects.js
Tuesday, May 4, 2010
15. DOM Access
• DOM Tree: Representação da estrutura da
página
• Render Tree: Representação de como os nós
do DOM devem ser mostrados.
Tuesday, May 4, 2010
16. DOM Access
• Quando uma mudança no DOM afecta a
geometria de um elemento (altura &
largura), o browser necessita de recalcular a
geometria desse elemento
Tuesday, May 4, 2010
17. DOM Access
• ... E a geometria e posição de todos os
elementos que possam ser afectados!!
• Este processo chama-se reflow.
• Quando o reflow acaba, o browser redesenha
as partes do documento afectadas (repaint)
Tuesday, May 4, 2010
18. DOM Access
• A maioria dos browsers optimiza o processo
de reflow com uma queue de mudanças.
• Podemos dar ordem (involutariamente, por
vezes) para esvaziar a queue...
Tuesday, May 4, 2010
19. DOM Access
• ... Quando são pedidas informações de
layout:
• offsetTop, offsetLeft, offsetWidth, offsetHeight;
• scrollTop, scrollLeft, scrollWidth, scrollHeight;
• clientTop, clientLeft, clientWidth, clientHeight
• getComputedStyle (currentStyle em IE)
Tuesday, May 4, 2010
20. DOM Access
• Enquanto mudamos estilos, devemos evitar
ler ou escrever estas propriedades.
• O número de reflows e repaints deve ser
reduzido ao máximo para evitar bloquear a
UI.
Tuesday, May 4, 2010
21. DOM Access
• Mudanças do DOM em batch:
• Retirar o elemento do flow do documento
• Aplicar todas as mudanças
• Trazer o elemento de volta ao documento
dom.js
Tuesday, May 4, 2010
22. Event Delegation
• 1000+ elementos no DOM com event
listeners (!!!!)
• Quantos mais handlers, mais tempo
demoram a ser atribuídos (isto geralmente
acontece em onLoad ou
DOMContentReady!!!)
• Também gasta memória armazenar info
sobre todos os handlers na página!
Tuesday, May 4, 2010
23. Event Delegation
• No DOM, os eventos bubble up, ou seja,
alastram desde o elemento que dispara o
evento até à root do documento (a menos
que sejam impedidos por instruções
especiais)
Tuesday, May 4, 2010
24. Event Delegation
• Podemos assim criar um delegate, um único
handler de eventos, no topo do documento,
que se preocupe em lidar com todos os
eventos que lhe chegam a partir dos outros
elementos na página.
Event Delegation.js
Tuesday, May 4, 2010
27. Loops
• for ... in é bastante mais lento, pois necessita
de procurar propriedades de um objecto a
cada iteração
Tuesday, May 4, 2010
28. Loops
• Principais bottlenecks:
• Trabalho por iteração
• Número de iterações
loops.js
Tuesday, May 4, 2010
29. Loops
• Function based-iteration ($.each em jQuery)
é consideravelmente mais lento que loop-
based iteration, levando até 8 (!!) vezes mais
tempo a executar.
Tuesday, May 4, 2010
30. Lookup Tables
• São extremamente mais rápidas que switch
ou encadeamentos if-else, e melhoram a
legibilidade do código.
Tuesday, May 4, 2010
31. Lookup Tables
• Devem ser utilizadas quando existir um
mapeamento lógico entre uma chave e um
valor.
Tuesday, May 4, 2010
32. Lookup Tables
• Um switch deve ser utilizado se cada chave
requerer um conjunto de acções muito
específico, que seja impossível de abstrair.
Tuesday, May 4, 2010
33. Optimizar jQuery
• Cache de selectores!!!
• Event delegation ($.delegate e $.live)
• Esquecer $.each
Tuesday, May 4, 2010