Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is jQuery $("td:eq(0)") slower than $("td").eq(0)

I am using jQuery 1.7.1 and I'm trying to find out why the following code takes 4600 MS, if I change the :eq(0) to :first it is the same result.

$("tr:eq(0) td"); // x10000 takes 4600ms
$("tr").eq(0).find("td"); // x10000 takes 470ms

The second codes is almost 10 times as fast! And it's only written differently.

Also if I use a selector like, just selecting an ID or looking within a node:

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

I would say, if I pass an div#test would be faster than #test but it is 5 times slower. Why?

I have done all runs a couple of times and it is real slow if I do the same thing different.

Why is using the selector slower then using functions?

like image 786
Niels Avatar asked Dec 06 '11 14:12

Niels


2 Answers

Answer right from the horse's mouth:

Additional Notes:

Because :eq() is a jQuery extension and not part of the CSS specification, queries using :eq() cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use $("your-pure-css-selector").eq(index) instead.

I should add that the aforementioned querySelectorAll API is supported in all modern browsers, so it can be "indiscriminately" used as a drop-in replacement for getElementById etc.

like image 87
Jon Avatar answered Nov 03 '22 10:11

Jon


jQuery is built off the Sizzle library. Sizzle takes advantage of native browser calls wherever possible.

'tr' is a valid selector for querySelectorAll which operates very quickly. Once the list of 'tr' elements is acquired, .eq() simply does an index lookup which is very fast.

'tr:eq(0)' is not a valid selector, so it has to iterate over every element in the DOM.

This discrepancy in benchmarking is noted in the jQuery docs for :eq():

Because :eq() is a jQuery extension and not part of the CSS specification, queries using :eq() cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. For better performance in modern browsers, use $("your-pure-css-selector").eq(index) instead.

like image 6
zzzzBov Avatar answered Nov 03 '22 10:11

zzzzBov