Melhorando a performance do Javascript
Javascript está em todos os lugares hoje, nas mais variadas formas, com ou sem frameworks, em desktops, sites, apps. E é fácil ver que temos problemas com performance, ainda mais em dispositivos móveis e em sistemas mal programados ou com muitos recursos visuais, animações e dados.
O Javascript em si não é tão rápido como deveria, mas a cada dia a performance melhora. Vale dar uma olhada nesse site arewefastyet que mostra uma comparação entre as engines existentes, no geral e por sistema operacional.
Existem algumas iniciativas para melhorar a performance do Javascript, como o asmjs, emscripten, que nada mais é do que um subset do javascript, compilado num código bem difícil de entender, mas não é nada prático para projetos diários, então seguem algumas dicas práticas para adotar no nosso dia a dia com Javascript que melhoram a performance:
Defina os tipos de váriaveis e mantenha-os assim
No Javascript as váriaveis são dinâmicas, então uma hora elas podem ser um inteiro, depois virar uma string ou qualquer outra coisa. Evite isso, declarando o tipo e nunca mudando ele, nem misturando tipos em um objeto.
// evite misturar tipos em arrays e objetos
var arr = [1, "teste", {}, []];
var obj = { um: 1, dois: '2', tres: [3, 4] }
Vale conferir esse teste de performance no jsperf
Não reestruture objetos
Reestruturar objetos é lento, então, para maior rapidez:
- Evite usar o operador
delete
, é mais rápido definir a váriavel como `null
. Mas não significa que não deva usar, apenas use com parcimônia.- veja esse teste de delete comparado à null. delete é chega a ser 99% mais lento!
- Não adicione propriedades dinâmicamente. Defina seu objeto inteiro no início, mesmo que vazio, e depois defina os valores quando for o caso.
- aqui dá para ver que definir o objeto antes é até 70% mais rápido.
Cuidado com concatenação de strings
Existem várias maneiras de concatenar strings e alguns mitos sobre a melhor forma, além de diferenças de performance, por método, entre navegadores diferentes.
Segundo este teste usar os operadores +
, +=
, tão comuns, não são a melhor abordagem.
Na maioria dos navegadores, usar Array.join
e String.concat
são máis rápidos.
Escolha o método correto para RegExp
Temos maneiras diferentes de fazer algo usando , então conheça a diferença entre eles e saiba qual é o mais performático para seu problema.
Compare os métodos
Regex.exec
,Regex.test
,String.match
eString.search
Então se não precisa saber a posição de uma substring em outra, prefira String.indexOf
em vez de Regex.test
, por exemplo.
Cuide do escopo
Evite declarar váriaveis e funções no escopo global.
Porquê? o escopo global já possui muita coisa ( tente console.log(window)
no console para ver) e quando se declara algo globalmente, a cada vez que acessamos a váriavel ou função a engine tem que procurar no meio de tudo que já está lá, o que piora a performance.
Então use escopos locais, como em Closures e não tenha receio de criar escopos e subescopos, criando sua funções dentro de um único objeto.
O velho e óbvio "Você não precisa de jQuery"
Existem vários artigos falando sobre não usar jQuery ( ou outros frameworks), não vou entrar nesse ponto na profundidade que eles abordam, mas em um pequeno detalhe:
Não é porque seu projeto TEM jQuery que você PRECISA usar jQuery
Entendem a diferença? um exemplo:
$('.meu_select').on('change', function(){
var valor = '';
// Para que usar
valor = $(this).val();
// em vez do nativo
valor = this.value;
});
Veja uma comparação de performance aqui.
Aprenda sobre os seletores nativos, propriedades, etc, pois usando eles irá escrever um código mais performático.
Vale a dica de sempre olhar no console como é o objeto, um simples console.log(meuobjeto)
ou console.log(this)
economiza muito tempo as vezes.
Já é hora de usar os Web Workers
Conhece Web Workers? Se não, deveria.
Basicamente é uma maneira de executar algum processo em background, assíncrono, sem interferir no seu processo principal
Ainda não temos suporte em todos navegadores mais usados, mas se sua aplicação é ie10+ você já pode usar sem medo. Veja o suporte aqui
Resumo prático
- Defina váriaveis no início e não mude o tipo delas;
- Não altere tipos de váriaveis ou de propriedades de um objeto;
- Concatene strings usando
Array.join
; - Evite o escopo global;
- Prefira Javascript nativo;
- Conversão de números: prefira
parseInt(numero, 10)
- teste; - No jQuery use `
prototype
em vez de$.extend
- teste; - O
for
nativo é sempre melhor que loops implementados teste; - Prefira o
for
mesmo em relação àforEach
efilter
- teste; - Use
call
em vez deapply
- teste; - Prefira
removeNode()
em vez deinnerHTML = ''
para limpar algo - teste - Selecione elementos por #ID
getElementById
- teste - No jQuery acesse elementos usando DOM em vez de
.first()
ou.eq()
- teste; - Crie textos com
createTextNode
em vez deinnerHTML
- teste; - O óbvio: evite loops aninhados;
- O velho: evite acessos ao DOM;
- Não preciso mencionar nada de
eval()
, certo?
Conclusão
Resumindo, boa parte das boas práticas nada mais são do que definir a váriável, objeto, no início na sua forma final, com tipo, chaves que serão usadas, e evitar modificá-los ao longo do código. Basicamenteé evitar usar a tipagem dinâmica do Javascript, que tem seu custo em performance.
Fora isso é conhecer os métodos apropriados para cada operação, diferença entre técnicas e ter em mente a finalidade da aplicação, já que cada browser ou dispositivo pode ter uma performance diferente para um mesmo código.
Alguns dos testes de performance entre métodos mostram pouca diferença, de 2% ou 3%, mas buscar a melhor performance em cada parte da sua aplicação irá fazer uma diferença significativa ao final pela soma das pequenas melhorias.
Essa é uma lista básica de pequenas melhorias para nosso dia a dia. Conhece mais alguma? Contribua, comente!