Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are jQuery's :first and :eq(0) selectors functionally equivalent?

I'm not sure whether to use :first or :eq(0) in a selector. I'm pretty sure that they'll always return the same object, but is one speedier than the other?

I'm sure someone here must have benchmarked these selectors before and I'm not really sure the best way to test if one is faster.

Update: here's the bench I ran:

/* start bench */
for (var count = 0; count < 5; count++) {
    var i = 0, limit = 10000;
    var start, end;
    start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $thisFrame.parents("div.RadEditor.Telerik:eq(0)");
    }
    end = new Date();
    alert("div.RadEditor.Telerik:eq(0) : " + (end-start));
    var start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $thisFrame.parents("div.RadEditor.Telerik:first");
    }
    end = new Date();
    alert("div.RadEditor.Telerik:first : " + (end-start));
    start = new Date();
    for (i = 0; i < limit; i++) {
        var radeditor = $thisFrame.parents("div.RadEditor.Telerik")[0];
    }
    end = new Date();
    alert("(div.RadEditor.Telerik)[0] : " + (end-start));
    start = new Date();
    for (i = 0; i < limit; i++) {
        var $radeditor = $($thisFrame.parents("div.RadEditor.Telerik")[0]);
    }
    end = new Date();
    alert("$((div.RadEditor.Telerik)[0]) : " + (end-start));
}
/* end bench */

I assumed that the 3rd would be the fastest and the 4th would be the slowest, but here's the results that I came up with:

FF3:    :eq(0)  :first  [0] $([0])
trial1  5275    4360    4107    3910
trial2  5175    5231    3916    4134
trial3  5317    5589    4670    4350
trial4  5754    4829    3988    4610
trial5  4771    6019    4669    4803
Average 5258.4  5205.6  4270    4361.4

IE6:    :eq(0)  :first  [0] $([0])
trial1  13796   15733   12202   14014
trial2  14186   13905   12749   11546
trial3  12249   14281   13421   12109
trial4  14984   15015   11718   13421
trial5  16015   13187   11578   10984
Average 14246   14424.2 12333.6 12414.8

I was correct about just returning the first native DOM object being the fastest ([0]), but I can't believe the wrapping that object in the jQuery function was faster that both :first and :eq(0)!

Unless I'm doing it wrong.

like image 915
travis Avatar asked Aug 05 '09 15:08

travis


3 Answers

2018: Yes, :first and :eq(0) return the same result although the performance difference would be marginal and perhaps even trivial in 2018.

2010: Good question and great post. I tested this some while ago and couldn't remember the exact outcome. I'm really glad to have found this because it's precisely what I was looking for.

I would guess that the reason for :first and :eq(0) being a tad slower is most likely related to parsing performance. Omitting these allows the jQuery engine to utilize the native getElementsByTagName and getElementsByClassName functions.

No surprises i.t.o. the DOM element being the fastest to access. Wrapping the DOM element with jQuery in a for loop won't necessarily have an adverse effect on performance as jQuery makes use of an expando property for caching purposes.

However, it would be interesting to see how get(0) compares with DOM element access and how the jQuery wrapping thereof fares against eq(0) and the rest of the results.

like image 40
WynandB Avatar answered Oct 07 '22 18:10

WynandB


According to jQuery's source code, .first() is just a convenience wrapper for .eq(0):

first: function() {
    return this.eq( 0 );
},

This remains true as of JQuery/3.6.0.

like image 66
Álvaro González Avatar answered Oct 07 '22 17:10

Álvaro González


Yes they are equivalent.

No they aren't likely to be significantly different (anything else is micro-optimization).

like image 20
cletus Avatar answered Oct 07 '22 19:10

cletus