Erros comuns de Javascript que afetam gravemente o desempenho? [fechadas]

10

Em um recente MeetUp de UI / UX que participei, dei alguns comentários em um site que usava Javascript (jQuery) para sua interação e interface do usuário - eram animações e manipulação bastante simples, mas o desempenho em um computador decente era horrível.

Na verdade, ele me lembrou muitos sites / programas que eu já vi com o mesmo problema, onde certas ações simplesmente destroem o desempenho. É principalmente em (ou pelo menos mais perceptível em) situações em que o Javascript está quase servindo como um substituto do Flash. Isso contrasta fortemente com alguns dos aplicativos da web que eu usei, que possuem muito mais Javascript e funcionalidade, mas funcionam muito bem (o COGNOS da IBM é um dos que eu consigo pensar).

Eu adoraria conhecer alguns dos problemas comuns que não são considerados no desenvolvimento de JS que prejudicam o desempenho do site.

Nic
fonte
Provavelmente o mesmo que em todos os outros programas: fazendo mais trabalho do que o necessário e fazendo o mesmo trabalho repetidamente, muitas vezes centenas de vezes.
11
@ delnan isso é muito verdade, mas parece que é muito mais prevalente em JS. Percepção, talvez?
Nic
11
Está ficando um pouco exagerado falar do 'site' quando se fala em JavaScript. Está em toda parte e está sendo usado para tudo nos dias de hoje.
Adam Crossland
@ Adam Crossland, você está absolutamente certo - nesse mesmo exemplo, acho que ajudei um desenvolvedor com um aplicativo nativo que dependia muito do jQuery também.
Nic
11
Não é exatamente uma resposta à sua pergunta, por isso faço um comentário: experimentei situações em que o JavaScript fez muita renderização e, na verdade, foi o mecanismo de renderização do navegador que consumiu os segundos. Portanto, para lidar com um gargalo de desempenho, procuraria primeiro operações de renderização desnecessárias.
precisa saber é o seguinte

Respostas:

8

Um assassino de desempenho comum está chamando .lengthuma HTMLCollection dentro de um forloop:

function foo(collection) {
    for (var index = 0; index < collection.length; index++) {
        // do something awesome here
    }
}

Esse anti-padrão faz com que o tamanho da coleção seja calculado em cada passagem pelo loop. A melhor abordagem é calcular o comprimento fora do loop:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}
Adam Crossland
fonte
3
Depende do navegador. Tome esta referência como exemplo: no FF 5, o "normal" é executado praticamente ao mesmo tempo que a versão "otimizada". E mesmo em navegadores muito antigos e lentos, algo assim provavelmente não será um gargalo se o JS realmente fizer algo de interesse com os elementos.
11
Hmm! Talvez os compiladores JIT altamente otimizadores de hoje estejam obsoletos.
Adam Crossland
4
Não sou um especialista de verdade aqui, mas, segundo as especificações da ECMA, parece que o comprimento é apenas uma propriedade do objeto de matriz. Assim, chamar apenas retorna valor em vez de contar todos os elementos. Não faço ideia se todas as implementações seguem as especificações, mas se o fizerem, seu código não melhora o desempenho.
Jacek Prucia
4
@JacekPrucia Ele disse coleção , não matriz - geralmente, em código real, isso significaria uma lista de elementos DOM retornados por funções como document.getElementsByTagName. A função retorna um live nodeListque recalcula seu comprimento toda vez que a .lengthpropriedade é acessada.
Yi Jiang
2
O benchmark @JacekPrucia é uma melhoria de desempenho. A pesquisa de propriedades não é barata.
Raynos 01/07/11
4

Não, o problema não vem do JS usado como substituição de flash. Se você não está convencido disso, documente-se sobre o actionscript: é muito próximo do JS.

Como matador de performances, você pode encontrar várias práticas ruins:

  • Anexe o manipulador de eventos em um evento contínuo, como rolagem, movimentação do mouse ou objetos semelhantes. Isso tem duas desvantagens: se o evento não for disparado o suficiente, seu aplicativo não será reativo. Se for acionado demais, você terá uma enorme carga de CPU por nada.
  • Fazendo chamadas síncronas AJAX. Javascript não é multithread, então, quando uma parte do JS está esperando por algo, seu aplicativo é congelado. É melhor usar chamadas AJAX assíncronas e da mesma forma que usar setTimeout / setInterval para dividir uma longa fase de computação e manter seu aplicativo reativo.
  • Alta complexidade de algoritmo, como em qualquer outro idioma.
deadalnix
fonte
Eu vi mais do que alguns aplicativos tentar girar, facilidade, ou animar imagens com navegadores completos e falhar miseravelmente no processo - que é onde o comentário de substituição do Flash decorre :)
Nic
Como o primeiro A no AJAX significa assíncrono, tecnicamente não é o AJAX se for síncrono, mas seu argumento ainda é bom.
Karl Bielefeldt
Sim, certo, não é estritamente AJAX. Mas de qualquer maneira, isso deve ser evitado: D
deadalnix
3

Eu dei alguns comentários em um site que usava Javascript (jQuery) para sua interação e interface do usuário - eram animações e manipulação bastante simples, mas o desempenho em um computador decente era horrível.

O maior problema com o desempenho é usar abstrações de alto nível (como jQuery) sem entender o modelo DOM subjacente e o modelo de animação CSS3 (ou canvas ou svg).

Se você não souber fazê-lo sem as abstrações, terá um conhecimento zero absoluto de quais técnicas são rápidas ou lentas.

Aprenda JavaScript, Aprenda o DOM. Depois de conhecer esses dois e saber o que suas abstrações fazem sob o capô, você poderá usá-las com eficiência. É claro que na maioria das vezes você percebe que a abstração é lenta e apenas manualmente, sem uma biblioteca.

Raynos
fonte
1

A beleza e a desvantagem do Javascript é que ele é extremamente flexível. Dito isto, ele realmente permite que você faça coisas que provavelmente não deveria fazer em muitos casos.

Das revisões de código das quais faço parte, as principais preocupações tendem a estar relacionadas à renderização de CSS. Para desenvolvedores JS mais recentes, tendemos a ver muitas variáveis ​​sendo usadas no escopo global.

Além disso, fechamentos inadequados geralmente podem causar vazamentos de memória. No entanto, a maioria das estruturas Javascript modernas evita esses tipos de problemas, desde que seu código siga a estrutura.

It Grunt
fonte
0

Aqui está um link rápido que eu encontrei há um ano para escrever um código jquery melhor: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

Uma coisa que acabei de encontrar em um código de colegas de trabalho que estava matando o desempenho foi o cache de dados que não precisavam ser armazenados em cache.

Exemplo:

var table = $("#data").dataTable(.....);

DataTables é um plug-in jQuery que usamos para criar grades agradáveis. De qualquer forma, a tabela tinha quase 5 mil linhas, aplicando o plug-in DataTables e salvando-o na variável da tabela, na verdade, o FireFox e o IE avisaram que um script estava demorando muito. Moral da história, apenas armazene em cache os dados se necessário.

Tyanna
fonte
11
Parece que o DataTables é um plugin realmente ineficiente / ruim, e não um problema com o cache. 5k não é nada.
Raynos 01/07/11
@ Raynos: Ele disse 5k linhas , não 5 kilobytes de dados. Uma "linha" pode ser uma coisa muito grande.
Chris Farmer
@ ChrisFarmer Se uma "linha" é muito grande, você tem um problema diferente .
Raynos 01/07/11
-1

Pelo que ouvi, os forloops são computacionalmente mais rápidos que os do jQuery $.each().

prótese
fonte
3
Isso é uma resposta de brincadeira?
Raynos 01/07/11