47 votes

La traversée de jQuery est-elle préférée aux sélecteurs?

Est l'aide de $("#vacations").find("li").last() est une meilleure pratique de $("#vacations li:last")?

Arrière-plan de mes pensées:

Je jouais avec une belle interactive essayer jQuery tutoriel et l'une des tâches dit:

Comme vous êtes à la recherche par le biais de votre code, vous remarquez que quelqu'un d'autre est de sélectionner les dernières vacances avec: $("#vacances li:last"). Vous regardez cela et vous pensez, "la Traversée ferait de cette façon, plus vite!" Vous devez agir sur ces pensées, refactoriser ce code pour trouver le dernier li sein de #vacances à l'aide de la traversée de la place.

Pourquoi penserais-je donc? Pour moi l'utilisation de sélecteurs ressemble un peu niveau plus élevé que celui de la traversée. Dans mon esprit quand je suis en spécifiant un sélecteur, il est à jQuery comment mieux obtenir le résultat dont j'ai besoin (sans besoin de revenir sur les résultats intermédiaires).

Qu'est-ce que qu'une charge supplémentaire de l'aide d'un composite de sélecteurs? Est-ce parce que la mise en œuvre actuelle de sélecteurs logique juste analyse de la chaîne et utilise la traversée de l'API? Analyse une chaîne de caractères qui est lent? Est-il possible qu'une mise en œuvre future va utiliser le fait qu'il n'a pas besoin de revenir sur les résultats intermédiaires et sera plus rapide que la traversée?

21voto

the system Points 5563

Il n'y a pas coupé et sec réponse à cela, mais à l'égard de l' :last sélecteur vous utilisez, c'est une extension propriétaire de la Sélecteurs API standard. De ce fait, il n'est pas valable pour une utilisation avec le natif .querySelectorAll méthode.

Ce Grésillement n'est, fondamentalement, essayez d'utiliser votre sélecteur .querySelectorAll, et si elle déclenche une Exception due à une défaillance de sélecteur, il sera par défaut à un niveau purement basé sur JavaScript DOM de sélection/de filtrage.

Cela signifie notamment les sélecteurs comme :last va vous amener à ne pas obtenir le boost de vitesse de DOM sélection avec le code natif.

En outre, il y a des optimisations inclus de sorte que lorsque le sélecteur est très simple, comme juste une ID ou un nom d'élément, le natif getElementById et getElementsByTagName seront utilisés, qui sont extrêmement rapide, même plus rapide que l' querySelectorAll.

Et depuis l' .last() méthode attrape le dernier élément de la collection au lieu de filtrer tous les éléments, ce qui est le Grésillement des filtres normalement (au moins ils ont utilisé pour), qui sera également chargé de donner un coup de pouce.

OMI, tenir à l'écart de la propriété des choses. Maintenant que .querySelectorAll est quasiment omniprésent, il y a de réels avantages à l'utilisation conforme aux normes de sélecteurs. Faire toute autre filtrage post DOM sélection.


Dans le cas d' $("#vacations").find("li"), ne vous inquiétez pas sur les résultats provisoires. Cela permettra d'utiliser getElementById suivie par getElementsByTagName, et sera extrêmement rapide.

Si vous êtes vraiment super inquiète de la vitesse, de réduire votre utilisation de jQuery, et d'utiliser le DOM directement.


Vous pourrez trouver les notes dans les docs pour les sélecteurs comme :last, qui vous avertissent de la perte de performances:

Parce que :le dernier est une extension jQuery et ne fait pas partie de la spécification CSS, requêtes à l'aide d' :last ne peuvent pas tirer parti de l'augmentation des performances fournies par les natifs de DOM querySelectorAll() méthode. Pour obtenir les meilleures performances lors de l'utilisation d' :last pour sélectionner des éléments, sélectionnez d'abord les éléments à l'aide d'un pur sélecteur CSS, puis utilisez .filter(":last").

Mais je serais en désaccord qu' .filter(":last") serait un bon substitut. Bien mieux serait de méthodes comme .last() qui lui permettront de cibler l'élément directement au lieu de filtrage de l'ensemble. J'ai le sentiment qu'ils veulent juste les gens de continuer à utiliser leur non-conforme aux normes de sélecteurs. OMI, vous êtes mieux de simplement les oublier.

14voto

Blender Points 114729

Voici un test de votre configuration: http://jsperf.com/andrey-s-jquery-traversal

Grésillement, jQuery sélecteur de moteur, analyse de la chaîne de regex et tente d'accélérer très les sélecteurs de base en utilisant getElementById et getElementsByTagName. Si le sélecteur est quelque chose de plus compliqué que d' #foo et img, il va essayer d'utiliser querySelectorAll, qui accepte uniquement valable sélecteurs CSS (pas de :radio, :eq, :checkbox ou autre jQuery-pseudo-sélecteurs).

Le sélecteur de chaîne est à la fois moins lisible et plus lent, donc, il n'y a vraiment pas de raison de l'utiliser.

En brisant le sélecteur de chaîne simple, de morceaux de Grésillement peut analyser rapidement (#id et tagname), vous êtes essentiellement juste en enchaînant les appels à l' getElementById et getElementsByTagName, ce qui est à peu près aussi vite que vous pouvez obtenir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X