¿Errores comunes de Javascript que afectan gravemente el rendimiento? [cerrado]

10

En una reciente reunión de UI / UX MeetUp a la que asistí, di algunos comentarios sobre un sitio web que usaba Javascript (jQuery) para su interacción e interfaz de usuario: eran animaciones y manipulaciones bastante simples, pero el rendimiento en una computadora decente fue horrible.

En realidad, me recordó a muchos sitios / programas que he visto con el mismo problema, donde ciertas acciones simplemente destruyen el rendimiento. Es principalmente en (o al menos más notable en) situaciones en las que Javascript casi sirve como reemplazo de Flash. Esto está en marcado contraste con algunas de las aplicaciones web que he usado que tienen mucho más Javascript y funcionalidad, pero se ejecutan sin problemas (COGNOS by IBM es una de las que se me ocurre).

Me encantaría conocer algunos de los problemas comunes que no se consideran al desarrollar JS que matarán el rendimiento del sitio.

Nic
fuente
Probablemente lo mismo que con cualquier otro programa: hacer más trabajo del necesario y hacer el mismo trabajo una y otra vez, a menudo cientos de veces.
1
@delnan eso es muy cierto, pero parece que es mucho más frecuente en JS. ¿Percepción tal vez?
Nic
1
Se está volviendo algo aburrido hablar de 'el sitio' cuando se habla de JavaScript. Está en todas partes y se usa para todo en estos días.
Adam Crossland
@ Adam Crossland tiene toda la razón: en esa misma instancia, creo que ayudé a un desarrollador con una aplicación nativa que también dependía en gran medida de jQuery.
Nic
1
No es exactamente una respuesta a su pregunta, por lo que hago un comentario: he experimentado situaciones en las que JavaScript realizó una gran cantidad de representación, y en realidad fue el motor de representación del navegador el que consumió los segundos. Por lo tanto, para manejar un cuello de botella de rendimiento, primero buscaría operaciones de renderizado innecesarias.
user281377

Respuestas:

8

Un asesino de rendimiento común está solicitando .lengthuna colección HTMLC dentro de un forbucle:

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

Ese antipatrón hace que el tamaño de la colección se calcule en cada pasada a través del bucle. El mejor enfoque es calcular la longitud fuera del ciclo:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}
Adam Crossland
fuente
3
Depende del navegador. Tome este punto de referencia como ejemplo: en FF 5, el "normal" se ejecuta casi al mismo tiempo que la versión "optimizada". E incluso en navegadores muy viejos y lentos, algo como esto probablemente no será un cuello de botella si el JS realmente hace algo de interés con los elementos.
1
Hmm! Quizás los compiladores JIT altamente optimizadores de hoy en día están volviendo obsoleta esta sabiduría.
Adam Crossland
44
No soy un verdadero experto aquí, pero según las especificaciones de ECMA parece que la longitud es solo una propiedad del objeto de matriz. Entonces llamarlo solo devuelve valor en lugar de contar todos los elementos. No tengo idea si todas las implementaciones siguen las especificaciones, pero si lo hacen, su código no mejora el rendimiento en absoluto.
Jacek Prucia 01 de
44
@JacekPrucia Dijo que la colección , no la matriz , por lo general, en código real, esto significaría una lista de elementos DOM devueltos por funciones como document.getElementsByTagName. La función devuelve un live nodeListque vuelve a calcular su longitud cada vez que .lengthse accede a la propiedad.
Yi Jiang
2
El punto de referencia de @JacekPrucia es una mejora del rendimiento. La búsqueda de propiedades no es barata.
Raynos
4

No, el problema no proviene de JS utilizado como reemplazo de flash. Si no está convencido con eso, documente su información sobre actionscript: está muy cerca de JS.

Como asesino de actuaciones, puedes encontrar varias malas prácticas:

  • Adjunte el controlador de eventos en eventos continuos, como desplazarse, mover el mouse o cosas similares. Esto tiene 2 inconvenientes: si el evento no se activa lo suficiente, su aplicación no será reactiva. Si se dispara demasiado, tendrá una gran carga de CPU por nada.
  • Realización de llamadas síncronas AJAX. Javascript no es multiproceso, entonces, cuando una parte de JS está esperando algo, su aplicación se congela. Es mejor que use llamadas AJAX asíncronas, y de la misma manera use setTimeout / setInterval para dividir una larga fase de cálculo y mantener su aplicación reactiva.
  • Alta complejidad del algoritmo como en cualquier otro idioma.
deadalnix
fuente
He visto más de unas pocas aplicaciones que intentan rotar, facilitar o animar imágenes de navegador completo y fallan miserablemente en el proceso, de ahí proviene el comentario de reemplazo de Flash :)
Nic
Dado que la primera A en AJAX significa asíncrono, técnicamente no es AJAX si es sincrónico, pero su punto sigue siendo bueno.
Karl Bielefeldt
Sí, claro, no es estrictamente AJAX. Pero de todos modos, esto debe evitarse: D
deadalnix
3

Di algunos comentarios sobre un sitio web que usaba Javascript (jQuery) para su interacción e interfaz de usuario: eran animaciones y manipulaciones bastante simples, pero el rendimiento en una computadora decente era horrible.

El mayor problema con el rendimiento es usar abstracciones de alto nivel (como jQuery) sin comprender el modelo DOM subyacente y el modelo de animación CSS3 (o lienzo, o svg).

Si no sabe cómo hacerlo sin las abstracciones entonces usted tiene absoluta cero conocimiento de qué técnicas son rápidos o lentos.

Aprenda JavaScript, aprenda el DOM. Una vez que conozca esos dos y sepa lo que hacen sus abstracciones debajo del capó, puede usarlos de manera eficiente. Por supuesto, la mayoría de las veces te das cuenta de que la abstracción es lenta y simplemente hacerlo manualmente sin una biblioteca.

Raynos
fuente
1

La belleza y el inconveniente de Javascript es que es extremadamente flexible. Dicho esto, en realidad te permite hacer cosas que probablemente no deberías hacer en muchos casos.

De las revisiones de código de las que he formado parte, las principales preocupaciones tienden a estar relacionadas con la representación de CSS. Para los nuevos desarrolladores de JS, tendemos a ver que se utilizan demasiadas variables en el ámbito global.

Además, los cierres inadecuados a menudo pueden causar pérdidas de memoria. Sin embargo, la mayoría de los marcos JavaScript modernos previenen este tipo de problemas siempre que su código siga el marco.

Gruñe
fuente
0

Aquí hay un enlace rápido que encontré hace aproximadamente un año sobre cómo escribir un mejor código jquery: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance / /

Una cosa que acabo de encontrar en un código de compañeros de trabajo que estaba matando el rendimiento era el almacenamiento en caché de datos que no era necesario almacenar en caché.

Ejemplo:

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

DataTables es un complemento de jQuery que usamos para hacer grids agradables. De todos modos, la tabla tenía casi 5k filas, la aplicación del complemento DataTables y luego guardarlo en la variable de la tabla en realidad hizo que tanto FireFox como IE advirtieran que un script estaba tardando demasiado. Moraleja de la historia, solo almacena en caché los datos si es necesario.

Tyanna
fuente
1
Parece que DataTables es un complemento realmente ineficiente / pobre en lugar de un problema con el almacenamiento en caché. 5k no es nada.
Raynos
@Raynos: Dijo 5k filas , no 5 kilobytes de datos. Una "fila" podría ser algo muy grande.
Chris Farmer
@ChrisFarmer Si una "fila" es algo muy grande, entonces tienes un problema diferente .
Raynos
-1

Por lo que he escuchado, los forbucles son computacionalmente más rápidos que los de jQuery $.each().

pttesis
fuente
3
¿Es esta una respuesta de broma?
Raynos