Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most appropriate way to get this: $($(".answer")[0])

Suppose I want to get the first element amongst all the elements of the class ".answer"

$($(".answer")[0])

I can do the above, but what is the best balance between elegance and speed?

*changed the question to reflect the current discussion

like image 202
meow Avatar asked Jan 29 '11 16:01

meow


3 Answers

The following are all equivalent in functionality (though not speed):

  • var a0 = $($('.answer')[0]);
  • var a0 = $('.answer').first(); - see http://api.jquery.com/first/
  • var a0 = $('.answer:first'); - see http://api.jquery.com/first-selector/
  • var a0 = $('.answer').eq(0); - see http://api.jquery.com/eq/
  • var a0 = $('.answer:eq(0)'); - see http://api.jquery.com/eq-selector/

Which is the best?
It has been hypothesized that the selector versions should be faster than the method versions (and the logic makes some sense) but I have not yet found a reliable cross-browser, multi-document benchmark that proves this to be true.

And in some cases you cannot use the selector, as you have a jQuery object resulting from chained results and must later pare it down.

Edit: Based on the excellent information from @yc's tests below, following are the current (2011-Feb-4) test results summarized and compared against a baseline of .answer:first:

          :first  :eq(0)  .first()  .eq(0)  $($('...')[0])
Chrome 8+   100%     92%      224%    266%       367%
   FF 3.6   100%    100%      277%    270%       309%
  FF 4.0b   100%    103%      537%    521%       643%
 Safari 5   100%     93%      349%    352%       467%
 Opera 11   100%    103%      373%    374%       465%
     IE 8   100%    101%     1130%   1246%      1767%
 iPhone 4   100%     95%      269%    316%       403%
=====================================================
 Weighted   100%     92%      286%    295%       405%
    Major   100%     95%      258%    280%       366%
  • The Weighted line shows the performance weighted by the number of tests per browser; popular browsers (among those testing) are counted more strongly.
  • The Major line shows the same, only including non-beta releases of the major desktop browsers.

In summary: the hypothesis is (currently) wrong. The methods are significantly faster than the Sizzle selectors, and with almost no exception the OP's code $($('.answer')[0]) is the fastest of them all!

like image 21
Phrogz Avatar answered Oct 31 '22 15:10

Phrogz


I can't speak to the elegance aspect, but the performance aspect here actually can make a huge difference.

It looks like, from a set of JavaScript testing, that your original method is actually the most efficient one, and contrary to the hypothesizing that the accepted answer linked to, non-CSS Sizzle selectors tend to be much less efficient than method selectors. There's a reason for that. The $('.answer') can use the browser native getElementsByClass() without having to manually traverse the results. The :first selector complicates that. In this instance, using the sizzle selectors seems to slow the selection by a factor of between 4-5.

I'd argue that, with jQuery, performance should trump elegance, and all evidence (every single browser I've tested so far!) seems to indicate that OP's inelegant solution is the fastest by a fair amount.

Here are the results of the browsers with the most test runs:

enter image description here

(The numbers are 'operations per second', so higher numbers are faster, lower numbers are slower.)

like image 199
Yahel Avatar answered Oct 31 '22 16:10

Yahel


Use the :first selector or the .first filter method:

$(".answer:first");

or:

$(".answer").first();
like image 10
karim79 Avatar answered Oct 31 '22 16:10

karim79