Tuesday, April 14, 2009

Essential Selector - Cross Browser LightWeight Selector Engine

Thanks to new DOM methods introduced recently in most common browser, e.g. querySelectorAll, we will not hopefully need full libraries to implement common CSS selectors. Nowadays, this could be the basement to create any kind of selector engine but we are still stack with old fashion browsers a la Internet Explorer version 6 or 7, both far away from W3 standards and with the slowest JavaScript engine in browsers panorama.

At the same time, whatever great selector API/engine we have under control, most used selectors are really few:

  • #id

  • .class

  • tag

  • tag.class



Reasons behind this fact are different, but in my opinion the most valid one is that Web Developers use CSS selectors in the same way they create CSS files and since CSS has become standard only recently thaks to Internet Explorer full CSS 2.1 support (n.d. other browsers are working on the CSS 3 since ages ...) our CSS files and our selectors will be that simple for long time.

Accordingly, and since we have some intermediate and cool prototype such getElementsByClassName, all we could need is just a basic selector engine able to retrieve nodes in the fastest possible way.

Of course, if querySelectorAll is present, this method will be a must, but what if it is not available?

Sizzle library is one of the most famous selectors engine so far, but we need "to move" 4KB of minified and gzipped code (not that much but often more than necessary) to obtain something simple, specially if precedent selectors are the only one we use in our project.

The Essential Selector Library

Maybe it sounds obvious, but to cover first 3 selectors in the list all we need is the fast getElementById, the standard getElementsByTagName, and the un-standard getElementsByClassName, easy to implement for old browsers. querySelectorAll? Superfluous in this case, but obviously still welcome! Above 4 selectors are the only one considered for performances in my last tiny library: about 1Kb minified and gzipped, suited for libraries and/or GUI development.
You can have a look directly in my repository to understand what will perform truly fast in every browser and what will perform in a reasonable time.

Essential Selector Philosophy

#id, .class, tag, and tag.class selectors will be fast for every browser while more complex selectors will be browser dependent. The main focus is into most used selectors but if you decide to use a specific one:

// CSS selector example
$e("div ul.myclass p");

recent browsers will perform in about 1 milliseconds while old browsers will perform a clean runtime CSS specific modification. This means that these browsers will have approximately the same delay for a selector like "div p" and "div p #content ul li.testcase" but at least, if the selector is compatible with the browser CSS engine, the result will be the same for every browser.
Moreover, due to the light size of the library, those bugged browsers will not be perfectly supported. As example, thre is a version of Opera which does not understand className in upper case ... well, this is not our problem, it is a browser specific bug so the browser vendor should solve it. The same is for other weird cases ... come on, we cannot consider every alpha/beta/unstable/intermediate/old version, so if the CSS works, the browser will respond as expected.
This is the philosophy behind this simple selector engine, where a search like

$e("div p")

will make sense, while another one like

$e("div[class^=whatever]")

will not, because of the not yet that standard chose selector.

Summary

Do you want a small footprint selector which works OK with daily basis environments? Try out Essential Library, otherwise I just gave you a valid, full compatible, alternative ;)

No comments:

Post a Comment