9
votes

Pourquoi JQuery $ ("TD: EQ (0)") est plus lent que $ ("TD"). EQ (0)

J'utilise JQuery 1.7.1 et j'essaie de savoir pourquoi le code suivant prend 4600 ms, si je modifie le : eq (0) code> sur : premier Code> C'est le même résultat.

someparent.find("#test") // x10000 takes 500ms
$("#test") // x10000 takes 100ms
$("div#test") // x10000 takes 470ms


1 commentaires

Firefox 8.0 J'utilise actuellement, mais je m'attends à ce que cela prend plus de temps dans tous les navigateurs.


4 Réponses :


6
votes

jQuery est construit sur le bibliothèque de Sizzille . Sizzle profite des appels de navigateur natifs dans la mesure du possible.

'tr' est un sélecteur valide pour QuerySelectorall qui fonctionne très rapidement. Une fois que la liste des éléments 'tr' est acquis, .eq () fait simplement une recherche d'index qui est très rapide.

'tr: eq (0)' n'est pas un sélecteur valide, il doit donc itération sur chaque élément du DOM.

Cette divergence dans l'analyse comparative est notée dans le JQUERY DOCS pour : EQ () :

parce que : eq () est une extension de jQuery et ne faisant pas partie de la spécification CSS, les requêtes utilisant : eq () ne peut pas tirer parti du boost de performance fourni par la Native DOM QuerySelectorall () Méthode. Pour de meilleures performances dans les navigateurs modernes, utilisez $ ("ton-pure-css-sélectoral"). EQ (index) à la place.


0 commentaires

1
votes

jQuery n'a pas besoin de diviser la chaîne d'entrée en fonctions et de convertir cette séquence de fonctions de chaîne en appels de méthode appropriés.


0 commentaires

0
votes

Je ne sais pas exactement pourquoi, mais je fais un problème similaire dans une autre langue et cela dépend de la fonction elle-même:

$ ("tr: eq (0) td"); doit être analysé pour fonctionner, puis effectuer l'appel de la fonction.

$ ("tr"). EQ (0) .Find ("TD"); seulement la fonction appelle


0 commentaires

18
votes

Répondre directement de la bouche du cheval :

Remarques supplémentaires:

parce que : eq () est une extension de jQuery et non partie de la spécification CSS, requêtes utilisant : EQ () Impossible de tirer parti de la performance Boost fournie par le Native DOM QuerySelectorall () méthode. Pour de meilleures performances dans les navigateurs modernes, utilisez $ ("ton-pure-css-sélectoral"). EQ (index) à la place.

Je devrais ajouter que le QuerySelectorall API est pris en charge dans tous navigateurs modernes , il peut donc être "indiscriminé" utilisé comme une Remplacement Drop-in pour GetElementyID etc.


8 commentaires

Donc, la raison pour laquelle : premier enfant est réel rapide, c'est parce qu'il s'agit d'un sélecteur CSS 3? Donc, j'ai besoin d'utiliser : premier enfant ou diviser mes requêtes.


La première partie est claire, mais pourquoi la recherche de l'identifiant est-elle plus lente si j'ai défini un parent? Je pensais que si je lui donne un parent, il n'est pas nécessaire de boucler tous les nœuds.


@Niels, : premier enfant n'est pas le même que : EQ (0) .


@Niels: parce que c'est un sélecteur CSS3 qui est également pris en charge par les navigateurs - si JQuery était obligé de l'imiter sur un navigateur, le résultat serait différent. Quant au sélecteur d'identifiant avec le parent ou non: probablement parce que sans parent, JQuery l'alimente directement à GetElementyID ou équivalent, tandis qu'avec un parent, il doit également marcher sur l'élément avec Cet identifiant a réellement le parent spécifié.


Il suffit d'essayer une nouvelle pièce de code: $ ("# test A") => 700ms, $ ("# test"). Trouver ("A") => 300ms , vous ne pouvez pas savoir pourquoi parce que les deux sont des sélecteurs CSS valides.


@Niels: sous la hotte, différentes méthodes d'API natives seront utilisées. Le premier utilisera queryselectorall , et le second que je pense utiliser getElementyid suivi de getelementsbytagname , qui sera généralement extrêmement rapide et Généralement plus rapide que QuerySelectorall , qui est une méthode plus complexe et n'a pas autant d'années de peaufiner derrière elle.


En réponse au premier commentaire, c'est simplement parce qu'il s'agit d'un sélecteur CSS. QuerySelectorall () Accepte Tout sélecteur que le navigateur prend en charge dans une feuille de style, le cas échéant, que ce soit ou non, il est même parti de la norme.


@BoltClock Si vous avez un grand nombre d'éléments correspondant à votre sélection, il semble étrange que : eq (0) ne serait pas plus rapide parce que je pense que la méthode cesse d'itération après que le premier élément ait été trouvé où .eq (0) prendrait le résultat défini après que tout ait été récupéré. Je comprends que cela ne fonctionne pas de cette façon, mais est-ce parce que le sélecteur JQuery ne stocke pas les éléments actuels. Il stocke la requête pour ces éléments?