25 February 2015

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.
  • 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 e String.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.

veja uma comparação entre escopo global e interno

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 `prototypeem vez de $.extend- teste;
  • O for nativo é sempre melhor que loops implementados teste;
  • Prefira o for mesmo em relação à forEach e filter - teste;
  • Use call em vez de apply- teste;
  • Prefira removeNode() em vez de innerHTML = '' 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 de innerHTML- 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!

Leia mais