Question

Je recherche un moyen d'améliorer les performances du sélecteur d'un appel jQuery.Plus précisément, des choses comme ceci :

Est $("div.myclass") plus rapide que $(".myclass")

Je pense que cela pourrait être le cas, mais je ne sais pas si jQuery est suffisamment intelligent pour limiter d'abord la recherche par nom de balise, etc.Quelqu'un a-t-il des idées sur la façon de formuler une chaîne de sélection jQuery pour obtenir de meilleures performances ?

Était-ce utile?

La solution

Ça ne fait aucun doute que le filtrage par nom de balise est d'abord beaucoup plus rapide que de filtrer par nom de classe.

Ce sera le cas jusqu'à ce que tous les navigateurs implémentent getElementsByClassName de manière native, comme c'est le cas avec getElementsByTagName.

Autres conseils

Dans certains cas, vous pouvez accélérer une requête en limitant son contexte.Si vous disposez d'une référence d'élément, vous pouvez la transmettre comme deuxième argument pour limiter la portée de la requête :

$(".myclass", a_DOM_element);

devrait être plus rapide que

$(".myclass");

si vous avez déjà un_DOM_element et qu'il est nettement plus petit que l'ensemble du document.

Comme Reid l'a déclaré ci-dessus, jQuery fonctionne de bas en haut.Bien que

cela signifie $('#foo bar div') est beaucoup plus lent que $('bar div #foo')

Ce n'est pas le propos.Si tu avais #foo de toute façon, vous ne mettriez rien avant dans le sélecteur puisque les identifiants doivent être uniques.

Le problème est le suivant :

  • si vous sous-sélectionnez quelque chose dans un élément avec un ID, sélectionnez d'abord ce dernier, puis utilisez .find, .children etc.: $('#foo').find('div')
  • votre partie la plus à gauche (première) du sélecteur peut être une mise à l'échelle moins efficace vers la partie la plus à droite (dernière) qui devrait être le plus efficace - c'est-à-dire que si vous n'avez pas de pièce d'identité, assurez-vous de la rechercher $('div.common[slow*=Search] input.rare') plutôt que $('div.rare input.common[name*=slowSearch]') - puisque cela n'est pas toujours applicable, assurez-vous de forcer l'ordre du sélecteur en le divisant en conséquence.

Afin de bien comprendre ce qui est plus rapide, vous devez comprendre comment fonctionne l'analyseur CSS.

Le sélecteur que vous transmettez est divisé en parties reconnaissables à l'aide de RegExp, puis traité pièce par pièce.

Certains sélecteurs comme ID et TagName utilisent l'implémentation native du navigateur qui est plus rapide.Alors que d'autres, comme la classe et les attributs, sont programmés séparément et sont donc beaucoup plus lents, nécessitant de parcourir les éléments sélectionnés et de vérifier chaque nom de classe.

Alors oui pour répondre à ta question :

$('tag.class') est plus rapide que $('.class').Pourquoi?Dans le premier cas, jQuery utilise l'implémentation native du navigateur pour filtrer la sélection uniquement sur les éléments dont vous avez besoin.Ce n'est qu'alors qu'il lance l'implémentation plus lente de .class en filtrant ce que vous avez demandé.

Dans le second cas, jQuery utilise sa méthode pour filtrer chaque élément en saisissant la classe.

Cela s'étend plus loin que jQuery car toutes les bibliothèques javascript sont basées sur cela.La seule autre option consiste à utiliser XPath, mais elle n'est actuellement pas très bien prise en charge par tous les navigateurs.

Voici comment augmenter les performances de vos sélecteurs jQuery :

J'ajouterai une note que dans 99% des applications Web, même les applications lourdes en Ajax, la vitesse de connexion et la réponse du serveur Web vont piloter les performances de votre application plutôt que celles du javascript.Je ne dis pas que vous devriez écrire du code intentionnellement lent ou qu'il n'est généralement pas bon d'être conscient de ce que les choses sont susceptibles d'être plus rapides que d'autres.

Mais je me demande si vous essayez de résoudre un problème qui n'existe pas encore vraiment, ou même si vous optimisez quelque chose qui pourrait changement dans un avenir proche (par exemple, si davantage de personnes commencent à utiliser un navigateur prenant en charge getElementsByClassName() fonction mentionnée précédemment), ce qui rend votre code optimisé exécuté plus lentement.

Un autre endroit où rechercher des informations sur les performances est la page Analyse des performances des sélecteurs de Hugo Vidal Teixeira.

http://www.componenthouse.com/article-19

Cela donne un bon aperçu des vitesses pour le sélecteur par identifiant, le sélecteur par classe et le nom de balise de préfixe du sélecteur.

Les sélecteurs les plus rapides par identifiant étaient :$("#identifiant")

Le sélecteur le plus rapide par classe était :$('tag.class')

Donc, le préfixe par balise n'a aidé que lors de la sélection par classe !

J'ai été sur certaines listes de diffusion jQuery et d'après ce que j'y ai lu, elles filtrent probablement par nom de balise puis par nom de classe (ou vice versa si c'était plus rapide).Ils sont obsédés par la vitesse et utiliseraient n’importe quoi pour gagner un peu de performance.

De toute façon, je ne m'inquiéterais vraiment pas trop, à moins que vous n'exécutiez ce sélecteur des milliers de fois/s.

Si vous êtes vraiment inquiet, essayez de faire une analyse comparative et voyez lequel est le plus rapide.

Pensez à utiliser la bibliothèque Sequentially d'Oliver Steele pour appeler des méthodes au fil du temps plutôt que toutes en même temps.

http://osteele.com/sources/javascript/sequentially/

La méthode « éventuellement » vous aide à appeler une méthode après un certain temps à compter de son appel initial.La méthode « séquentiellement » vous permet de mettre en file d'attente plusieurs tâches sur une période donnée.

Très utile!

UN bon conseil à partir d'une question que j'ai posée :Utiliser sélecteurs CSS standards la mesure du possible.Cela permet à jQuery d'utiliser le API des sélecteurs.Selon tests effectués par John Resig, cela se traduit par des performances quasi natives pour les sélecteurs.Des fonctions telles que :has() et :contains() devrait être évité.

D'après mes recherches, le support de l'API Selectors a été introduit avec jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.

Si je ne me trompe pas, jQuery est également un moteur ascendant.Cela signifie $('#foo bar div') est beaucoup plus lent que $('bar div #foo').Par exemple, $('#foo a') passera par tous les a éléments sur la page et voir s'ils ont un ancêtre de #foo, ce qui rend ce sélecteur extrêmement inefficace.

Resig a peut-être déjà optimisé pour ce scénario (cela ne me surprendrait pas s'il le faisait - je crois qu'il l'a fait dans son moteur Sizzle, mais je n'en suis pas sûr à 100%).

Je pense que la sélection par ID d'abord est toujours plus rapide :

$("#myform th").css("color","red");

devrait être plus rapide que

$("th").css("color","red");

Cependant, je me demande dans quelle mesure le chaînage aide lorsqu'on commence par l'ID ?Est-ce

$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");

plus vite que ça ?

$("#myform th").css("color","red");
$("#myform td").css("color","blue");
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top