Are jQuery's :first and :eq(0) selectors funct

2019-01-25 05:10发布

问题:

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.

回答1:

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.



回答2:

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

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


回答3:

Yes they are equivalent.

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