I'm developing an application with jQuery and i was wondering what is the fastest method to select an element with jQuery, there are hundreds of elements in this web page and each one has an unique id, and i'm doing this:
$("#main-container").addClass("col-lg-12");
i know that's the slowest approach to do it, so i think the main question is what is faster?
// 1
$("#main-container").addClass("col-lg-12");
// 2
$(document.getElementById("main-container")).addClass("col-lg-12");
// 3
$(document.querySelector("#main-container")).addClass("col-lg-12");
Use something like http://jsperf.com/ for performance checks
Looks like $(document.getElementById("main-container")).addClass("col-lg-12"); is the fastest of those 3
http://jsperf.com/buttsnanananannana/6
If you're pananoid about performance though, you probably shouldn't be using jQuery. You can do this instead: document.getElementById('main-container').classList.add('col-lg-12')
If you're really interested about performance you shoulnd't use jQuery. That said if you want to have the fastest selection method you should be using the most JavaScript native specific selection method you can, like:
document.getElementById()
document.getElementsByTagName()
document.getElementsByClassName()
I understand that it is really easy to use the most generic ones:
document.querySelector()
document.querySelectorAll()
The thing with the last ones is that they're going to spend time looking if your selector is a class or id, and/or if it's inside another elements.
However my recomendation for you is to use the specific ones every time you can, and if you want to use the jQuery thing and wrap them with it, well that is up to you.
There is a jsPerf for you:
As you can see in this chart, document.getElementById() is way faster than document.querySelector(). But when is wrapped into $() is like nine times slower than normal
$(document.getElementById("main-container")).addClass("col-lg-12"); will be the fastest selector out of the three that you've provided.
Related
I have to select every second <td> in each row of a table on my page.
Currently, im using the :nth-child() selector to get the target DOM. But I also find out another way to do this, which is using the .get() method.
The HTML and jQuery code is in this jsFiddle
My question is considering from the performance, which one is better?
You can create performance test cases on http://jsperf.com
As is, I'd say that :nth-child selector should behave quicker, though http://jsperf.com/nth-child-vs-get (at least for my browser) disproves it.
What is the best approach to creating elements in JavaScript? I know about creating element using:
string example:
var div="<div></div>"
And another way is using
document.CreateElement('div').
Which one is the best method to achieve high performance? Is there is any other way to achieve this?
There is no single "best" approach, the best thing to do varies with the situation.
You basically have two choices:
Use the DOM methods to create elements (document.createElement('tagName')) and append/insert them into the DOM (appendChild, insertBefore), or
Use innerHTML on an existing element, assigning an HTML string to it; the browser will parse and render the HTML.
It used to be, just a couple of years ago, that innerHTML was a lot faster. But modern versions of browsers have improved the speed of DOM access dramatically, so really it comes down to what works best for the overall task you're performing.
When you append that div="<div></div>" to your body like I'm sure you meant to do, that works fine but is inefficient.
If you create the element, it creates its own object. The first option using the div var will allocate memory for the string and then again for the object itself and you have to reference it separately anyway. Basically doubling the browser's work.
Are selectors or functions faster in jQuery? Example:
$('#something div.else'); // find multiple divs with class .else
or
$('#something').children('div.else');
I'm trying my best to optimize a page with hundreds of returned elements that seems to hang on a certain crappy computer here in the office (that must use Internet Explorer ::shudder::).
Well in this case, the second's faster, but, they're not equivalent. The first finds any descendant div.else, the other finds only direct children that are div.else.
It depends on your DOM as to which is faster, the equivalent of the second would be this:
$('#something > div.else');
This uses the child selector. They should be very, very close, and in any case, I doubt a selector descending from an ID is your problem area, I think you'll find the vast majority of your time in JS is spent elsewhere.
For diagnosing speed issues, get a profiler, for IE specifically there's a fantastic free one called dynaTrace AJAX Edition. Grab it, follow the short tutorials on their site...you'll find where your pain areas in IE are pretty quickly.
Although I haven't checked with the jQuery code, I think the difference should be negligable between your two examples - although the first one should run a little faster.
The problem with old IE versions is that they do not support a native way to fetch items based on class names. In this case, jQuery has to execute a regulra expression on each class attribute of each element contained.
If it is possible in your case, you might gain quite a lot performance when being able to select on an unusual tagname:
$("#container blockquote.else")
and ideally,leave away the class name.
EDIT: just saw the answer from Nick and he's right, the scond one only has to check the direct children. The equivalent first one would be:
$("#container > div.else")
In your specific example, your first example of
$('#something div.else');
gets optimized through Sizzle (which is delivered within the jQuery lib) into
$('#something').find('div.else');
without that optimization, it would be slower, since the selector engine sizzle does work from right to left. So, it would match all divs with the class else and would then check which of those has #something as parent.
edit
The Sizzle optimazation is slower
anyway, since it took a while until
that task is completed and some
functions are called on the way
In general, using jQuery functions is a lot faster. For instance jQuerys .eq() function will use an array slice to reduce a wrappet set of jQuery objects, whereas :eq() selector will invoke sizzle.
If in your example, div.else elements are direct children of #something, .children() will beat .find() since .find() will also lookup all descendants (and their childs).
If I understand correctly you need the fastest way to get #something div.else in IE6. Since jQuery uses Sizzle, the way it will find that is first find all div's, then filter by the ones with the else class, and has an ancestor with the #something id.
Your second example will be faster if it contains few children, slower if it contains many.
A suggestion you could try would be to use another tag type instead of div, one that isn't used in your page, say blockquote. Just reset it's styles with css so it looks like a normal div, then change your selector to #something blockquote.else which should be tons faster.
Is this faster:
$(document.links).filter('a.someClass')
than just plain old this:
$('a.someClass')
?
I don't see anywhere in jQuery's code the utilization of document.links
which gives you the collection of links on the document right away,
than, it would seem, it would be faster to just filter in the collection
instead of all the DOM nodes, which is alot more nodes to go over.
I just ran a test, running the selector 1000 times on Chrome.
$(document.links).filter('a.someClass') took 672 ms to run 1000 times.
$('a.someClass') took 191 ms to run 1000 times.
If you do
$('a').filter('.someClass') however, that takes 652 ms to run; so filter seems to be where the time is lost.
var x = $('.remove', document.links); coincidentally, took 13 seconds; so best not to use that variation :P
Theoretically, iterating document.links will be a bit faster than jQuery's Sizzle selector library. However:
not the way you're doing it with filter, which gives jQuery just as much work to do than it would have to do using Sizzle to pick the elements in the first place;
document.links won't necessarily give you exactly the same as $('a'), as a-without-href doesn't appear in the links collection.
the direct $('a.someClass') method will be much faster than even manually iterating document.links in modern browsers, because that method will just transfer control to the browser's own implementation of document.querySelectorAll('a.someClass'), which will be much faster than anything your or Sizzle could do sniffing at DOM Nodes yourself.
(There is one slightly faster method than querySelectorAll, which jQuery doesn't use yet: document.getElementsByClassName('someClass'). Again, it's only in modern browsers though, and IE8 doesn't have it where it does have querySelectorAll. In practice it's probably not worth bothering about too much as querySelectorAll is already very fast.)
Don't second-guess jQuery. Lots of people have spent lots of time making it fast. If it were the case that document.links were a good way to find <a> tags, then Sizzle would do it automatically for you.
That said (well, typed), it's definitely better to do this:
$('a.someClass')
than
$('.someClass')
When you can qualify your selectors with a tag name, you're better off. The engine will use getElementsByTagName() to cut down on the number of nodes to scan.
I'm not familiar with how the sizzle selector library works but I would suspect when you do $('a.someclass') that jQuery will retrieve all the anchors using something like document.getElementByTagName('A') rather than traversing the whole DOM.
As Pointy says, sizzle is very fast and highly optimised, best way to find out which is better would be to run your own benchmarks
I just ran a test here : http://jsbin.com/ixiva3
1000 links were created dynamically.
this test require firebug (using console.time)
Results shows that $("a.somelink") is the fastest.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I'm looking for any way that I can improve the selector performance of a jQuery call. Specifically things like this:
Is $("div.myclass") faster than $(".myclass")
I would think it might be, but I don't know if jQuery is smart enough to limit the search by tag name first, etc. Anyone have any ideas for how to formulate a jQuery selector string for best performance?
There is no doubt that filtering by tag name first is much faster than filtering by classname.
This will be the case until all browsers implement getElementsByClassName natively, as is the case with getElementsByTagName.
In some cases, you can speed up a query by limiting its context. If you have an element reference, you can pass it as the second argument to limit the scope of the query:
$(".myclass", a_DOM_element);
should be faster than
$(".myclass");
if you already have a_DOM_element and it's significantly smaller than the whole document.
As Reid stated above jQuery is working from the bottom up. Although
that means $('#foo bar div') is a
lot slower than $('bar div #foo')
That's not the point. If you had #foo you wouldn't put anything before it in the selector anyway since IDs have to be unique.
The point is:
if you are subselecting anything from an element with an ID then select the later first and then use .find, .children etc.: $('#foo').find('div')
your leftmost (first) part of the selector can be less efficient scaling to the rightmost (last) part which should be the most efficient - meaning if you don't have an ID make sure you are looking for $('div.common[slow*=Search] input.rare') rather than $('div.rare input.common[name*=slowSearch]') - since this isn't always applicable make sure to force the selector-order by splitting accordingly.
In order to fully comprehend what is faster, you have to understand how the CSS parser works.
The selector you pass in gets split into recognizable parts using RegExp and then processed piece by piece.
Some selectors like ID and TagName, use browser's native implementation which is faster. While others like class and attributes are programmed in separately and therefore are much slower, requiring looping through selected elements and checking each and every class name.
So yes to answer your question:
$('tag.class') is faster than just $('.class'). Why?
With the first case, jQuery uses the native browser implementation to filter the selection down to just the elements you need. Only then it launches the slower .class implementation filtering down to what you asked for.
In the second case, jQuery uses it's method to filter each and every element by grabbing class.
This spreads further than jQuery as all javascript libraries are based on this. The only other option is using xPath but it is currently not very well supported among all browsers.
Here is how to icrease performance of your jQuery selectors:
Select by #id whenever possible (performance test results ~250 faster)
Specify scope of your selections ($('.select', this))
I'll add a note that in 99% of web apps, even ajax heavy apps, the connection speed and response of the web server is going to drive the performance of your app rather than the javascript. I'm not saying the you should write intentionally slow code or that generally being aware of what things are likely to be faster than others isn't good.
But I am wondering if you're trying to solve a problem that doesn't really exist yet, or even if you're optimizing for something that might change in the near future (say, if more people start using a browser that supports getElementsByClassName() function referred to earlier), making your optimized code actually run slower.
Another place to look for performance information is Hugo Vidal Teixeira's Performance analysis of selectors page.
http://www.componenthouse.com/article-19
This gives a good run down of speeds for selector by id, selector by class, and selector prefixing tag name.
The fastest selectors by id was: $("#id")
The fastest selector by class was: $('tag.class')
So prefixing by tag only helped when selecting by class!
I've been on some of the jQuery mailing lists and from what I've read there, they most likely filter by tag name then class name (or vice versa if it was faster). They are obsessive about speed and would use anything to gain a smidgen of performance.
I really wouldn't worry about it too much anyway unless you are running that selector thousands of times/sec.
If you are really concerned, try doing some benchmarking and see which is faster.
Consider using Oliver Steele's Sequentially library to call methods over time instead of all at once.
http://osteele.com/sources/javascript/sequentially/
The "eventually" method helps you call a method after a certain period of time from its initial call. The "sequentially" method lets you queue several tasks over a period of time.
Very helpful!
A great tip from a question I asked: Use standard CSS selectors wherever possible. This allows jQuery to use the Selectors API. According to tests performed by John Resig, this results in near-native performance for selectors. Functions such as :has() and :contains() should be avoided.
From my research support for the Selectors API was introduced with jQuery 1.2.7, Firefox 3.1, IE 8, Opera 10, Safari 3.1.
If I am not mistaken, jQuery also is a bottom up engine. That means $('#foo bar div') is a lot slower than $('bar div #foo'). For example, $('#foo a') will go through all of the a elements on the page and see if they have an ancestor of #foo, which makes this selector immensely inefficient.
Resig may have already optimized for this scenario (it wouldn't surprise me if he did - I believe he did in his Sizzle engine, but I am not 100% certain.)
I believe that selecting by ID first is always faster:
$("#myform th").css("color","red");
should be faster than
$("th").css("color","red");
However, I wonder how much chaining helps when starting with the ID? Is this
$("#myform").find("th").css("color","red")
.end().find("td").css("color","blue");
any faster than this?
$("#myform th").css("color","red");
$("#myform td").css("color","blue");