-1

When referencing elements in jQuery, which of the following is most efficient:

HTML:

<div id="divId" class="divClass">Div</div>

jQuery:

var div = $('div');
var div = $('#divId');
var div = $('.divClass');

Also considering compound references:

HTML:

<main id="mainId" class="mainClass">
    <div id="divId" class="divClass">Div</div>
</main>

jQuery:

var mainDiv = $('main div');
var mainDiv = $('#mainId #divId');
var mainDiv = $('.mainClass .divClass');
Stuart Kershaw
  • 16,831
  • 6
  • 37
  • 48
  • in jquery: `$(document.getElementById('divId'));` – A. Wolff Nov 27 '13 at 18:41
  • 2
    [http://jsperf.com](http://jsperf.com/jquery-simplest-selector-efficiency) – Blazemonger Nov 27 '13 at 18:41
  • I don't know the correct answer, but you could use the [profiles tool](https://developers.google.com/chrome-developer-tools/docs/profiles) in the chrome developer tools to see what takes the shortest time/least cpu. – echochamber Nov 27 '13 at 18:41
  • Using pure javascript is the fastest. If you want to use JQuery, as you are in your example, it does not matter if you select something using the ID or Class. Either way is searching the DOM for that tag. – David Aguirre Nov 27 '13 at 18:42
  • It also depends on the browser. If the browser does not have a native selector implementation, or is missing `getElementsByTag`, etc. those will be "slower." `getElementById` has always been native, and should perform the best of all. It really depends on if the DOM engine has a cache or not, and what is cached during document parsing/rendering. – zamnuts Nov 27 '13 at 18:43
  • Question already answered: http://stackoverflow.com/questions/15393928/jquery-class-selector-vs-id-selector – Parkash Kumar Nov 27 '13 at 18:46
  • 2
    Since `id`s are by definition unique, `$('#mainId #divId');` is redundant. – steveax Nov 27 '13 at 18:47
  • 1
    @steveax Sometimes it's useful to use nested ID selectors, if you want to test whether the descendant element has been moved out of a container. – Blazemonger Nov 27 '13 at 18:49

2 Answers2

4

Using the ids with var mainDiv = $('#mainId #divId'); will perform best.

See the results of this jsperf

If your targeting the inner div just use the straight id selector $("#divId") which is way faster: jsperf. Using two ids in the selector actually slows things down.

Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • jQuery will also use native `document.getElementsByClassName` If the browser supports it. – steveax Nov 27 '13 at 18:46
  • @steveax And the `id` will outperform the `class`: http://jsperf.com/anothertest – Kevin Bowersox Nov 27 '13 at 18:48
  • Indeed it will, but not because it's native, but rather that it's searching for a single element rather than (possibly) many elements. – steveax Nov 27 '13 at 18:50
  • @steveax I think the best solution is not listed, `$("#divId")`, which you have already mentioned. – Kevin Bowersox Nov 27 '13 at 18:52
  • 1
    @KevinBowersox: for the `$('#mainId #divId')` example, jQuery will use `.querySelectorAll`, or the Sizzle engine if `qSA` isn't available. It'll only use `getElementById` for simple selectors like `#foo`. – Blue Skies Nov 27 '13 at 18:56
3

It also depends on the browser. If the browser does not have a native selector implementation, or is missing getElementsByTagName and getElementsByClassName, etc. those will be "slower." getElementById has always been native (as far back as I can remember), and should perform the best of all. It really depends on if the DOM engine has a cache or not, and what is cached during document parsing/rendering.

Remember, jQuery uses Sizzle under the hood, so this isn't really a question about jQuery, but Sizzle.

Sizzle attempts to use native DOM traversing methods, like matchSelector, where possible. In some cases where a shiv is needed (like a :not(:has(span:eq(6))))) non-native DOM traversal is required.

You should consider the complexity of the selector query, and from what part of the DOM tree the selector starts. Limiting your query is always faster than always starting from the root of the DOM: e.g. $('#main').find('.someClass') or $('#main .someClass')¹ as opposed to $('.someClass').

Perhaps this question is too open-ended.

¹ Per @nick-f, "Sizzle processes the selectors from right to left" so $('#main .someClass') is not synonymous with $('#main').find('.someClass').

Community
  • 1
  • 1
zamnuts
  • 9,492
  • 3
  • 39
  • 46
  • Thanks for your thoughts, very interesting stuff. Your point about Sizzle under the hood is well taken. Surprised about the downvotes on the question, but I think you're right... too open-ended. – Stuart Kershaw Nov 27 '13 at 22:14
  • @StuartKershaw yw, and yea, I'm surprised they didn't close it as off-topic/too broad, and still haven't! your question is valid in my opinion, i generally disagree with closing types of questions like yours since *they are helpful*, they just generate really bad answers. where else are you going to put it other than SO? IRC? a forum? bah! – zamnuts Nov 27 '13 at 22:37
  • 2
    For what it's worth, `$('#main').find('.someClass')` and `$('#main .someClass')` are actually not the same. The former will limit your query as you suggest (find the element by id, then search within it), but the latter will actually find all `.someClass` elements first, then filter by parent elements. This is because Sizzle processes the selectors from right to left. – Nick F Apr 08 '15 at 10:18