In version 2.4.0 YUI got its own Selector Utility allowing you to use CSS 3 Selectors to find nodes. This means you can write the selector query:
var nodes = YAHOO.util.Selector.query('input[name^=yui]');
and nodes will contain all the input elements whose name attribute begins with "yui".
As this timeline indicates this is a feature in common with a number of other JavaScript libraries and something that is bound to be used more and more often.
But before you go off a play with your shiny new plaything I'd like to share the results of some profiling that I did with you.
Initially I did this profiling after someone suggested to me that
YAHOO.util.Event.onDOMReady(
function() {
var nodes = YAHOO.util.Dom.getElementsByClassName(...);
// Do something AMAZING with the nodes
}
);
might be slow - i.e. that YAHOO.util.Dom.getElementsByClassName() might struggle with large or complex documents. Since we use this technique for some of our widgets I wanted to make sure that what we were doing was as fast as possible.
To get an idea of the relative performance of a variety of techniques I grabbed the source of a page that had recently been the subject of debate at work (thinking it to at least be a somewhat realistic example) and compared the following techniques to find table elements with a class name of "Table":
YAHOO.util.Dom.getElementsByClassName('Table');YAHOO.util.Dom.getElementsByClassName('Table', 'table');YAHOO.util.Selector.query('[class~="Table"]');YAHOO.util.Selector.query('table.Table');$('.Table');$('table.Table');For the last two techniques I used jQuery as it has supported CSS3 Selectors for a while and I wanted to see how it performed relative to YUI, given the YUI implementation is in beta. Also note that there is a bug in the initial version of the YUI Selector Utility that means the class selector does not work if the class name begins with a capital letter, this means I tested YAHOO.util.Selector.query('[class~="Table"]'); rather than YAHOO.util.Selector.query('.Table'); and as the results (which we'll get to in a second) indicate comparing [class~="Table"] to .Table might not be a fair comparison.
These results are for Firefox 2 running on an HP Compaq 6910p with 2GB of RAM and Windows XP Professional SP 2.
| Technique | Time (s) |
|---|---|
| YUI DOM ('Table') | 0.9162 |
| YUI DOM ('Table', 'table') | 0.0062 |
| YUI Selector ('[class~="Table"]') | 2.9312 |
| YUI Selector ('table.Table') | 0.0092 |
| jQuery ('.Table') | 1.2674 |
| jQuery ('table.Table') | 0.0144 |
What these numbers tell us:
table elements with class="Table" is much faster than looking for any element with class="Table".[class~="Table"] and table.Table as equivalent tests). However I'm reluctant to conclude that the YUI Selector implementation is faster than the jQuery one across the board.For round two I focused on the fastest queries and tried 10,000 iterations of each:
| Technique | Time (s) |
|---|---|
| YUI DOM ('Table', 'table') | 1.743 |
| YUI Selector ('table.Table') | 4.8714 |
From this I think we can conclude:
YAHOO.util.Dom.getElementsByClassName it should outperform a selector query.I guess those points deserve a little more explanation.
On the first point, I have seen people write selectors that look like this:
var nodes = YAHOO.util.Selector.query('div#Foo a.Bah');
i.e. get all the a elements with class="Bah" that are descendants of the element with id="Foo".
Because an id should be unique on the page this can be rewritten as:
var nodes = YAHOO.util.Dom.getElementsByClassName('Bah', 'a', 'Foo');
(or even var nodes = YAHOO.util.Selector.query('a.Bah', 'Foo');) which should run faster today and, I would wager, in the future as more browsers implement getElementsByClassName natively (I'm assuming YUI decides to delegate to the native implementation at some point in the future).
The second point, however, suggests that if you minimise the scope of your selector query your shiny new plaything should be acceptably performant unless you have an unusually complex document.
I'm a software architect living in Queenstown, New Zealand.