Is jQuery crawl preferable for selectors?

Is $("#vacations").find("li").last() better than $("#vacations li:last") ?

History and my thoughts:

I played with a nice interactive try jQuery tutorial , and one of the tasks says:

When you look at your code, you notice that someone else is choosing the last vacation with: $ ("# vacations li: last"). You look at it, and you think, "Traverse will do it faster!" You should act on these thoughts, reorganize this code to find the last li in #vacations, using a bypass instead.

Why do I think so? For me, using selectors looks a little higher than an intersection. In my opinion, when I specify a selector, it depends on jQuery how best to get the only result that I need (without the need to return intermediate results).

What is this additional overhead for using composite selectors? Is it because the current implementation of selector logic just parses the string and uses the traversal API? Parses a string that slows down? Is it likely that a future implementation will use the fact that it does not need to return intermediate results and will be faster than a workaround?

+45
performance javascript jquery
Mar 05 '13 at 5:58
source share
2 answers

There is no answer to this question, but regarding the :last selector that you use, it is a proprietary extension of the Selectors API standard. Because of this, this is not valid for use with the native .querySelectorAll method.

That Sizzle is basically trying to use your selector with .querySelectorAll , and if it throws an exception due to an invalid selector, it will use JavaScript based DOM select / filter by default.

This means that turning on selectors like :last will result in you not getting DOM acceleration with your own code.

In addition, optimizations are included, so when your selector is very simple, for example, only the identifier or element name, the native getElementById and getElementsByTagName will be used, which are very fast; usually even faster than querySelectorAll .

And since the .last() method just grabs the last element in the collection, rather than filtering all the elements that Sizzle filters usually do (at least they were used), which will also give a boost.

IMO, stay away from proprietary material. Now that .querySelectorAll pretty ubiquitous, there are real benefits only with standard selectors. Make another choice of DOM filter message.




In the case of $("#vacations").find("li") do not worry about the intermediate results. This will use getElementById followed by getElementsByTagName and will be very fast.

If you are really very concerned about speed, reduce the use of jQuery and use the DOM directly.




Currently, you will find notes in the docs for selectors like :last , which warn you about performance loss:

Since: the latter is a jQuery extension and not part of the CSS specification, queries using :last cannot take advantage of the performance enhancement provided by the DOM's querySelectorAll() built-in method. For best performance when using :last to select elements, first select the elements using a clean CSS selector, then use .filter(":last") .

But I would not agree that .filter(":last") would be a good replacement. Much better would be methods like .last() , which would target the element directly, rather than filtering the set. I have a feeling that they just want people to continue using their custom selectors. IMO, you better just forget about them.

+21
Mar 05 '13 at 6:25
source share

Here is the test for your installation: http://jsperf.com/andrey-s-jquery-traversal

Sizzle , the jQuery selector, parses the string using a regular expression and tries to speed up the use of very simple selectors with getElementById and getElementsByTagName . If your selector is something more complex than #foo and img , it will try to use querySelectorAll , which only accepts valid CSS selectors (no :radio querySelectorAll :checkbox or other jQuery-specific pseudo-selectors).

The selector string is less readable and slow, so there is no reason to use it.

Parsing the selector chain into simple pieces that Sizzle can quickly parse ( #id and tagname ), you basically just connect the getElementById and getElementsByTagName calls, which is about as fast as you can get.

+14
Mar 05 '13 at 6:29
source share



All Articles