I’ve talked about this API before (1, 2) and while I do have some misgivings about the current API (which will be remedied in upcoming revisions of the spec) there is one thing that is undeniable about it: It is extraordinarily fast.
Thankfully, implementations haven’t scarified specification compatibility for performance and we can see both the Firefox and WebKit implementations coming in at 99.3% passing the Selectors API test suite. Opera is working on their implementations, slated for Opera 10, and Microsoft has an implementation in beta 1 of Internet Explorer 8. This means that by late this year all browsers will have an implementation of the Selectors API in the market.
- Dojo has querySelectorAll support in Dojo 1.1.1, although support for Safari 3.1 is disabled (there were troublesome crashing bugs in early versions of Safari 3.1 that have since been resolved).
- Prototype has querySelectorAll support in their Git repository (presumably to be rolled into their next release).
- jQuery has querySelectorAll support in an experimental plugin (to land in the next release).
|Prototype Git||9914 (123% slower than native, 351% faster than DOM)|
|jQuery 1.2.7 Plugin||4731 (7% slower than native, 641% faster than DOM)|
|Dojo 1.1.1||5669 (28% slower than native, 267% faster than DOM)|
That means that libraries that utilize querySelectorAll will be running 2-6x faster than their previous versions. This is already quite impressive.
There are two points to consider when using this API:
- That you need to try and keep the overhead on top of the querySelectorAll method as low as possible.
- That it becomes advantageous to avoid the querySelectorAll API in some extreme cases (for example, jQuery avoids it for #id queries, allowing it to go over 10x faster than querySelectorAll).
A lot of bare-bones selectors library implementations are going to look something like this:
document.querySelectorAll( selector ) );
return myOtherLibrary( selector );
Note two points: There’s a try-catch block there to capture any syntax errors that are generated by querySelectorAll (syntax errors could be generated by APIs that the implementation doesn’t understand – like jQuery’s div:first, for example). If no exception is thrown while retrieving the results we need to convert it into an array (most libraries convert result sets into arrays – or bless them in some manner).
Tackling both of these points will introduce some level of overhead in a library (on top of the native querySelectorAll implementation). Of course it’s never as simple as it should be, many libraries extend these return sets with additional functionality so the overhead will be that much greater.