Comment les débutants jQuery peuvent tester et améliorer leur code

L’arrivée de jQuery a rendu le processus d’écriture de JavaScript extrêmement facile. Cependant, vous remarquerez que les modifications mineures apportées à votre code améliorent considérablement la lisibilité et / ou les performances. Voici quelques astuces pour optimiser votre code..


Mise en place de la plateforme

Nous aurons besoin d'une plate-forme solide pour mener nos tests. Voici le balisage HTML de la page de test sur laquelle nous allons exécuter tous nos tests:

     Tester les améliorations de performances - Siddharth / NetTuts+   

Du texte ici

  • Oh bonjour là-bas!

Il n'y a rien de spécial ici; juste un tas d'éléments que nous pouvons cibler et tester. Nous utilisons Firebug pour enregistrer les temps ici. profil commence le processus, et profilFin l'arrête et note combien de temps a pris la tâche. J'utilise généralement la méthode du profil principal de Firebug, mais pour nos besoins sournois, cela sera suffisant.


1. Détecter si un élément existe

Comme c'est souvent le cas, vous ne servirez qu'un seul fichier de script contenant votre code sur toutes les pages de votre site. Il s'agit généralement d'un code qui exécute souvent des actions sur des éléments inexistants de la page en cours. Bien que jQuery gère des problèmes tels que ceux-ci de manière assez élégante, cela ne signifie pas que vous pouvez simplement ignorer les problèmes. En fait, si vous appelez les méthodes de jQuery sur une collection vide, elles ne seront pas exécutées..

Il est recommandé d’exécuter uniquement le code applicable à la page actuellement chargée, au lieu de regrouper l’ensemble de votre code dans un seul contrôle de document prêt et de le transmettre au client..

Regardons le premier scénario:

 console.profile (); var ele = $ ("# quelque chose qui ne se trouve pas ici"); ele.text ("Du texte"). slideUp (300) .addClass ("édition"); $ ("# mainItem"); console.profileEnd (); // Un peu plus génial, un code bouleversant, ici ._.

Firebug's crache le résultat suivant:

Cette fois, vérifions si l'élément sur lequel nous souhaitons effectuer des actions existe avant de le faire..

 console.profile (); var ele = $ ("# quelque chose qui ne se trouve pas ici"); if (ele [0]) ele.text ("Du texte"). slideUp (300) .addClass ("édition");  $ ("# mainItem"); console.profileEnd (); // Un peu plus génial, un code bouleversant, ici ._. 

Et les résultats:

Voir? C'est assez simple, au point et fait le travail. Notez que vous n'avez pas besoin de vérifier si un élément existe pour chaque bit de votre code.. Vous remarquerez dans votre page que certaines grandes parties bénéficieront généralement de cette méthode. Utilisez votre jugement ici.


2. Utiliser les sélecteurs efficacement

Essayez d'utiliser un identifiant au lieu de passer une classe.

C'est un sujet important, je vais donc le garder le plus concis possible. Tout d'abord, lorsque vous passez des sélecteurs, essayez d'utiliser un ID au lieu de transmettre une classe. jQuery utilise directement le natif getElementById méthode pour trouver un élément par ID alors que dans le cas d'une classe, elle doit faire un peu de vaudou interne pour l'acquérir, du moins dans les anciens navigateurs.

Nous allons examiner les différents sélecteurs que vous pouvez utiliser pour cibler le 2e li élément. Nous allons tester chacun d'eux et comment ils modifient les performances.

La première méthode, la plus simple, consistera à la cibler clairement en utilisant le choisi classe. Voyons ce que le profileur de Firebug retourne.

 console.profile (); $ (". sélectionné"); console.profileEnd (); 

Et le résultat: 0.308ms. Ensuite, nous préfixons un nom de tag pour le réduire. De cette façon, nous pouvons affiner notre recherche en ne ciblant d’abord que les éléments DOM sélectionnés, avec document.getElementsByTagName..

 console.profile (); $ ("li.selected"); console.profileEnd (); 

Et le résultat: 0.291ms. Environ 0,02 ms rasé. Ceci est négligeable en raison du fait que nous testons dans Firefox; Toutefois, il convient de noter que cette amélioration des performances sera considérablement plus élevée dans les navigateurs plus anciens, comme Internet Explorer 6..

Ensuite, nous descendons de l'ID de l'élément parent.

 console.profile (); $ ("# someList .selected"); console.profileEnd (); 

Et le résultat: 0.283ms. Essayons d'être un peu plus précis. Nous spécifions également le type d'élément en plus de l'ID de l'ancêtre.

 console.profile (); $ ("# someList li.selected"); console.profileEnd (); 

Et le résultat: 0,275 ms. Une autre petite partie rasée. Enfin, ciblons-le directement en utilisant un identifiant.

 console.profile (); $ ("# mainItem"); console.profileEnd (); 

Et le résultat: 0,165ms. Impressionnant! Cela montre vraiment à quel point les méthodes natives sont exécutées plus rapidement. Notez que, si les navigateurs modernes peuvent tirer parti d'éléments tels que getElementsByClassName, les navigateurs plus anciens ne peuvent pas, ce qui entraîne des performances beaucoup plus lentes. Considérez toujours ceci lors du codage.


3. Prise en compte du modèle d'analyse syntaxique de Sizzle et de l'ajout d'étendues

Sizzle, le moteur de sélection utilisé par jQuery - construit par John Resig - analyse les sélecteurs de droite à gauche, ce qui soulève quelques chaînes d'analyse inattendues..

Considérez ce sélecteur:

 $ ("# someList .selected"); 

Lorsque Sizzle rencontre un tel sélecteur, il construit d'abord la structure DOM, en utilisant le sélecteur comme racine, supprime les éléments qui ne possèdent pas la classe requise et, pour chaque élément de la classe, il vérifie si son parent a un ID de un peu de liste.

Pour en tenir compte, assurez-vous que la partie la plus à droite de votre sélecteur est aussi spécifique que possible. Par exemple, en spécifiant li.selected au lieu de .choisi, vous réduisez le nombre de nœuds à vérifier. C'est la raison pour laquelle les performances ont bondi dans la section précédente. En ajoutant des contraintes supplémentaires, vous réduisez efficacement le nombre de nœuds à vérifier.

Pour affiner la manière dont les éléments sont obtenus, vous devez ajouter un contexte à chaque demande..

 var someList = $ ('# someList') [0]; $ (". sélectionné", un peu de liste);

En ajoutant un contexte, la façon dont l'élément est recherché change complètement. Maintenant, l'élément fournissant le contexte - un peu de liste dans notre cas - est d'abord recherché, et une fois obtenu, les éléments enfants qui n'ont pas la classe requise sont supprimés.

Notez qu'il est généralement recommandé de passer un élément DOM en tant que contexte de votre sélecteur jQuery. L'utilisation d'un contexte est plus utile lorsqu'il est stocké dans une variable. Sinon, vous pouvez rationaliser le processus et utiliser find () - ce que jQuery lui-même fait sous le capot.

 $ ('# une liste'). find ('. sélectionné');

J'aimerais dire que l'augmentation de la performance sera clairement définie, mais je ne peux pas. J'ai effectué des tests sur un certain nombre de navigateurs afin de déterminer si les performances de cette approche dépassaient celles de la version vanilla en fonction d'un certain nombre de facteurs, notamment la prise en charge par le navigateur de méthodes spécifiques..


4. Évitez le gaspillage de requêtes

Lorsque vous parcourez le code de quelqu'un d'autre, vous trouverez souvent.

 // Autre code $ (élément) .doQuelque chose (); // Plus de code $ (élément) .doSomethingElse (); // Encore plus de code $ (élément) .doMoreofSomethingElse (); 

S'il vous plaît ne faites pas cela. Déjà. Le développeur instancie cet "élément" à plusieurs reprises. C'est du gaspillage.

Voyons combien de temps prend un tel code horrible.

 console.profile (); $ ("# mainItem"). hide (); $ ("# mainItem"). val ("Bonjour"); $ ("# mainItem"). html ("Oh, salut là-bas!"); $ ("# mainItem"). show (); console.profileEnd (); 

Si le code est structuré comme ci-dessus, l'un après l'autre, vous pouvez utiliser le chaînage comme suit:

 console.profile (); $ ("# mainItem"). hide (). val ("Bonjour"). html ("Oh, hé là!"). show (); console.profileEnd ();

En chaînant, l'élément initialement transmis est acquis et une référence est transmise à chaque appel suivant, réduisant ainsi le temps d'exécution. Sinon, un nouvel objet jQuery est créé à chaque fois..

Mais si, contrairement à ce qui précède, les sections référençant l'élément ne sont pas concurrentes, vous devrez le mettre en cache, puis effectuer les mêmes opérations que précédemment..

 console.profile (); var elem = $ ("# mainItem"); elem.hide (); // Some code elem.val ("Hello"); // More code elem.html ("Oh, salut là-bas!"); // Encore plus de code elem.show (); console.profileEnd (); 

Comme le montrent les résultats, la mise en cache ou le chaînage réduit considérablement le temps d'exécution.


5. Effectuer la manipulation DOM plus intelligemment

Suggérer des manipulations DOM non traditionnelles dans mon article précédent a attiré l'attention de quelques personnes avant de montrer que l'amélioration des performances en vaut vraiment la peine. Nous allons maintenant le tester nous-mêmes.

Pour le test, nous allons créer 50 li éléments, et les ajouter à la liste actuelle, et déterminer combien de temps il faut.

Nous allons d'abord examiner la méthode normale et inefficace. Nous ajoutons essentiellement l'élément à la liste chaque fois que la boucle s'exécute.

 console.profile (); var list = $ ("# someList"); pour (var i = 0; i<50; i++)  list.append('
  • Item # '+ i +'
  • '); console.profileEnd ();

    Voyons comment cela s'est passé, allons-nous?

    Maintenant, nous suivrons un chemin légèrement différent. Nous allons essentiellement ajouter la chaîne HTML requise à une variable sapin, puis rediffuser le DOM une seule fois..

     console.profile (); var list = $ ("# someList"); var items = ""; pour (var i = 0; i<50; i++) items += '
  • Item # '+ i +'
  • '; list.append (items); console.profileEnd ();

    Comme prévu, le temps mis a considérablement diminué.

    Si vous utilisez jQuery en remplacement de getElementById, mais que vous n'utilisez jamais l'une des méthodes fournies, vous le faites mal..

    Si vous souhaitez aller plus loin, demandez-vous s'il est vraiment nécessaire de créer un nouvel objet jQuery dans le but de cibler un élément? Si vous utilisez jQuery en remplacement de document.getElementById, mais que vous n'utilisez jamais l'une des méthodes fournies, vous le faites mal. Dans ce cas, nous pouvons nous en sortir avec du JS brut.

     console.profile (); var list = document.getElementById ('someList'); var items = "; pour (var i = 0; i<50; i++) items += '
  • Item # '+ i +'
  • '; list.innerHTML = items; console.profileEnd ();

    Quelques mises en garde

    Vous remarquerez que la différence de temps d'exécution entre le code optimisé et non optimisé est de l'ordre de la fraction de milliseconde. Ceci est dû au fait que notre document de test est très petit avec un nombre de nœuds incroyablement petit. Une fois que vous aurez commencé à travailler avec des sites de niveau de production comptant quelques milliers de noeuds, le nombre de nœuds augmentera..

    Notez également que dans la plupart de ces tests, j'accède simplement aux éléments. Lorsque vous commencez à leur appliquer les fonctions appropriées, le delta du temps d’exécution augmente.

    Je comprends aussi que ce ne sont pas les méthodes les plus scientifiques pour tester les performances, cependant, pour avoir une idée générale de l’impact de chacun de ces changements sur les performances, je pense que cela est suffisant..

    Enfin, dans la plupart de vos applications Web, la vitesse de connexion et le temps de réponse du serveur Web en question vont jouer un rôle plus important dans les performances de votre application que les ajustements apportés au code que vous allez modifier. Néanmoins, cela reste une information importante et vous aidera tout au long de la ligne lorsque vous essayez de tirer le maximum de performances de votre code..


    C'est tout les gens

    Et nous avons fini. Quelques points à garder à l'esprit lorsque vous essayez d'optimiser votre code; Ce n'est pas la liste complète des réglages, bien sûr, et les points peuvent ne pas s'appliquer nécessairement à toutes les situations. Quoi qu'il en soit, je suivrai de près les commentaires pour lire ce que vous avez à dire sur le sujet. Une erreur que vous voyez ici? Laissez-moi une ligne ci-dessous.

    Des questions? De belles choses à dire? Des reproches? Hit la section des commentaires et laissez-moi un commentaire. Bonne codage!