Petit conseil pensez de droite à gauche avec jQuery

En tant qu'anglophones, notre esprit est axé sur l'interprétation des données et du texte de gauche à droite. Cependant, il se trouve que beaucoup de moteurs de sélecteur JavaScript modernes (jQuery, YUI 3, NWMatcher) et le querySelectorAll, analyser les chaînes de sélecteur de droite à gauche.

Il est important de noter que, le plus souvent, vous n'avez pas à vous soucier de la performance du sélecteur, à condition que vos sélecteurs ne soient pas odieux. jQuery's Sizzle est incroyablement rapide et accommodant.


Un exemple

Considérons le sélecteur suivant:

 $ ('. box p');

Bien que certains moteurs de sélection - généralement les plus anciens - interrogent d’abord le DOM sur l’élément avec classe de boîte, puis passez à la recherche de p balises qui sont des enfants, jQuery fonctionne en sens inverse. Il commence par interroger le DOM pour tout balises de paragraphe sur la page, puis le fait remonter les nœuds parents et recherche .boîte.

JSPerf

Nous pouvons utiliser l'excellent site Web JsPerf.com pour le tester..

 // le balisage 

Bonjour

// Le test // 1. $ ('# box p'); // 2. $ ('# box'). Find ('p');

L'image ci-dessus montre que l'utilisation de trouver() ou enfants () est environ 20-30% plus rapide, selon le navigateur.

La bibliothèque jQuery a une optimisation qui déterminera immédiatement si un identifiant a été passé à l'objet jQuery ( $ ('# box') ). Si c'est le cas, il n'est pas nécessaire d'utiliser Sizzle; au lieu de cela, il passe rapidement le sélecteur à getElementById. Et bien sûr, si le navigateur est suffisamment moderne, querySelectorAll prendra la relève pour Sizzle.

Par contre, avec $ ('# box p'), jQuery doit analyser cette chaîne avec l’API Sizzle, ce qui prendra un peu plus de temps (bien que Sizzle ait une optimisation pour les sélecteurs commençant par un identifiant). C’est précisément pourquoi il est également légèrement plus rapide de faire des choses comme $ ('. elems'). first () plus de $ ('. elems: premier'). Ce dernier sélecteur devra être analysé.


Un autre exemple

Passons en revue un autre exemple:

 $ ('# conteneur>: désactivé');

Ce sélecteur semble approprié. Trouver toutes les entrées désactivées (ou réellement, les éléments) qui se trouvent dans #récipient. Cependant, comme nous l’avons appris, jQuery et le serveur natif querySelectorAll travailler de droite à gauche. Cela signifie que jQuery récupérera littéralement chaque élément du DOM et déterminera si sa désactivée attribut est défini sur true. Notez qu'il n'y a pas de préfiltrage pour trouver d'abord toutes les entrées de la page. Au lieu de cela, chaque élément du DOM sera interrogé.

 // Depuis la source jQuery disabled: function (elem) return elem.disabled === true; 

Une fois la collection compilée, elle se déplace ensuite dans la chaîne jusqu'au parent et détermine si elle est #récipient. Certes, cela n’est pas efficace et, s’il est vrai que la performance des sélecteurs est peut-être une trop grande attention de la part de la communauté, nous devrions quand même nous efforcer d’écrire des sélecteurs trop intensifs, lorsque cela est possible..

Vous pouvez améliorer un peu ce sélecteur en faisant:

 // Better $ ('# conteneur> input: disabled');

Ce code limitera la requête à toutes les entrées de la page en premier (plutôt que chaque élément). Mieux encore, nous pouvons encore utiliser le trouver ou les enfants méthode.

 $ ('# conteneur'). enfants ('entrée: désactivé');

Ne vous inquiétez pas trop

Il est important pour moi de répéter que, honnêtement, vous n'avez pas à vous soucier de la performance des sélecteurs. Il y a beaucoup d'optimisations dans jQuery qui vous aideront. Il est généralement préférable de se concentrer sur les articles les plus volumineux, tels que l'organisation et la structure du code..

Par exemple, si Sizzle rencontre un sélecteur comme $ ('# box p'), c’est vrai que cela fonctionne de droite à gauche, mais il existe aussi une optimisation rapide des expressions rationnelles qui déterminera d’abord si la première section du sélecteur est identifiant. Si c'est le cas, il utilisera cela comme contexte, lors de la recherche des balises de paragraphe.

Néanmoins, il est toujours utile de savoir ce qui se passe dans les coulisses - du moins à un niveau très bas.