Erreurs Javascript courantes qui affectent gravement les performances? [fermé]

10

Lors d'un récent Meetup UI / UX auquel j'ai assisté, j'ai donné quelques commentaires sur un site Web qui utilisait Javascript (jQuery) pour son interaction et son interface utilisateur - il s'agissait d'animations et de manipulations assez simples, mais les performances sur un ordinateur décent étaient horribles.

Cela m'a en fait rappelé de nombreux sites / programmes que j'ai vus avec le même problème, où certaines actions détruisent absolument les performances. C'est principalement dans (ou du moins plus visible dans) des situations où Javascript sert presque de remplacement Flash. C'est en contraste frappant avec certaines des applications Web que j'ai utilisées qui ont beaucoup plus de Javascript et de fonctionnalités mais fonctionnent très bien (COGNOS by IBM est celui auquel je peux penser du haut de ma tête).

J'adorerais connaître certains des problèmes courants qui ne sont pas pris en compte lors du développement de JS, ce qui tuera les performances du site.

Nic
la source
Probablement le même que pour tous les autres programmes: faire plus de travail que nécessaire et faire le même travail encore et encore, souvent des centaines de fois.
1
@delnan c'est très vrai, mais il semble que ce soit beaucoup plus répandu dans JS. La perception peut-être?
Nic
1
Il devient quelque peu faux de parler de «site» lorsque l'on parle de JavaScript. Il est partout et utilisé pour tout de nos jours.
Adam Crossland
@Adam Crossland, vous avez absolument raison - dans ce même cas, je pense que j'ai aidé un développeur avec une application native qui comptait également beaucoup sur jQuery.
Nic
1
Ce n'est pas exactement une réponse à votre question, donc j'en fais un commentaire: j'ai vécu des situations où JavaScript a fait beaucoup de rendu, et c'est en fait le moteur de rendu du navigateur qui a utilisé les secondes. Par conséquent, pour gérer un goulot d'étranglement des performances, je rechercherais d'abord les opérations de rendu inutiles.
user281377

Réponses:

8

Un tueur de performances commun appelle .lengthune HTMLCollection dans une forboucle:

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

Cet anti-modèle entraîne le calcul de la taille de la collection à chaque passage dans la boucle. La meilleure approche consiste à calculer la longueur en dehors de la boucle:

function foo(collection) {
    var collectionLen = collection.length;
    for (var index = 0; index < collectionLen; index++) {
        // do something awesome here
    }
}
Adam Crossland
la source
3
Dépend du navigateur. Prenez cette référence comme exemple: Dans FF 5, les pistes d' un « normal » dans à peu près en même temps que la version « optimisée ». Et même dans des navigateurs vraiment anciens et lents, quelque chose comme ça ne sera probablement pas un goulot d'étranglement si le JS fait réellement quelque chose d'intéressant avec les éléments.
1
Hum! Peut-être que les compilateurs JIT hautement optimisants d'aujourd'hui rendent ce peu de sagesse obsolète.
Adam Crossland
4
Je ne suis pas un vrai expert ici, mais d'après les spécifications de l'ECMA, il semble que la longueur ne soit qu'une propriété d'un objet tableau. Donc, l'appeler renvoie simplement de la valeur au lieu de compter tous les éléments. Aucune idée si toutes les implémentations suivent la spécification, mais si c'est le cas, votre code n'améliore pas du tout les performances.
Jacek Prucia
4
@JacekPrucia Il a dit que la collection , pas le tableau - généralement, dans du code réel, cela signifierait une liste d'éléments DOM retournés par des fonctions telles que document.getElementsByTagName. La fonction renvoie un live nodeListqui recalcule sa longueur à chaque .lengthaccès à la propriété.
Yi Jiang
2
Le benchmark @JacekPrucia est une amélioration des performances. La recherche de propriété n'est pas bon marché.
Raynos
4

Non, le problème ne vient pas de JS utilisé comme remplacement flash. Si vous n'êtes pas convaincu de cela, documentez-vous sur actionscript: il est très proche de JS.

En tant que tueur de performances, vous pouvez trouver plusieurs mauvaises pratiques:

  • Attachez un gestionnaire d'événements à un événement continu, comme le défilement, le déplacement de la souris ou d'autres éléments similaires. Cela a 2 inconvénients: si l'événement n'est pas suffisamment déclenché, votre application ne sera pas réactive. S'il est trop déclenché, vous aurez une énorme charge CPU pour rien.
  • Passer des appels AJAX synchrones. Javascript n'est pas multithread, alors, quand une partie de JS attend quelque chose, votre application est gelée. Il vaut mieux utiliser les appels AJAX asynchrones et utiliser de la même manière setTimeout / setInterval pour diviser une longue phase de calcul et garder votre application réactive.
  • Complexité d'algorithme élevée comme dans tous les autres langages.
deadalnix
la source
Je l' ai vu plus de quelques applications essayer de tourner, la facilité, ou animez des images navigateur complet et échouent lamentablement dans le processus - c'est là le commentaire de remplacement vient de flash :)
Nic
Puisque le premier A dans AJAX signifie asynchrone, techniquement ce n'est pas AJAX s'il est synchrone, mais votre point est toujours bon.
Karl Bielefeldt
Oui, ce n'est pas strictement AJAX. Mais de toute façon, cela doit être évité: D
deadalnix
3

J'ai donné quelques commentaires sur un site Web qui utilisait Javascript (jQuery) pour son interaction et son interface utilisateur - c'était des animations et une manipulation assez simples, mais les performances sur un ordinateur décent étaient horribles.

Le plus gros problème avec les performances est d'utiliser des abstractions de haut niveau (comme jQuery) sans comprendre le modèle DOM sous-jacent et le modèle d'animation CSS3 (ou canvas, ou svg).

Si vous ne savez pas comment le faire sans les abstractions, vous n'avez aucune connaissance absolue des techniques rapides ou lentes.

Apprenez JavaScript, apprenez le DOM. Une fois que vous connaissez ces deux et que vous savez ce que font vos abstractions sous le capot, vous pouvez les utiliser efficacement. Bien sûr, la plupart du temps, vous réalisez que l'abstraction consiste à ralentir et à le faire manuellement sans bibliothèque.

Raynos
la source
1

La beauté et l'inconvénient de Javascript est qu'il est extrêmement flexible. Cela étant dit, cela vous permet en fait de faire des choses que vous ne devriez probablement pas faire dans de nombreux cas.

D'après les révisions de code auxquelles j'ai participé, les principales préoccupations ont tendance à être liées au rendu CSS. Pour les nouveaux développeurs JS, nous avons tendance à voir beaucoup trop de variables utilisées dans la portée globale.

De plus, des fermetures incorrectes peuvent souvent provoquer des fuites de mémoire. Cependant, la plupart des frameworks Javascript modernes empêchent ce genre de problèmes tant que votre code suit le framework.

It Grunt
la source
0

Voici un lien rapide que j'ai trouvé il y a un an environ pour écrire un meilleur code jquery: http://net.tutsplus.com/tutorials/javascript-ajax/10-ways-to-instantly-increase-your-jquery-performance /

Une chose que je viens de découvrir dans un code de collègues qui détruisait les performances était la mise en cache des données qui n'avaient pas besoin d'être mises en cache.

Exemple:

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

DataTables est un plug-in jQuery que nous utilisons pour créer de belles grilles. Quoi qu'il en soit, la table contenait près de 5 000 lignes, en appliquant le plug-in DataTables puis en l'enregistrant dans la variable de table, FireFox et IE ont en fait averti qu'un script prenait trop de temps. Morale de l'histoire, ne cachez les données que si vous en avez besoin.

Tyanna
la source
1
On dirait que DataTables est un plugin vraiment inefficace / pauvre plutôt qu'un problème de mise en cache. 5k n'est rien.
Raynos
@Raynos: Il a dit 5 000 lignes , pas 5 kilo-octets de données. Une «rangée» pourrait être une chose très importante.
Chris Farmer
@ChrisFarmer Si une "ligne" est une chose très importante, alors vous avez un problème différent .
Raynos
-1

D'après ce que j'ai entendu, les forboucles sont plus rapides que celles de jQuery $.each().

thèse
la source
3
Est-ce une réponse de plaisanterie?
Raynos