A Javascript CSS3 Selector and Matcher not using XPath

NWMatcher 0.99.9 has been update on Google Code, it is at SVN 44 (20080803).

Straight to the TEST

The SLICKSPEED TEST courtesy of the Mootools team.

Numbers doesn't always show the truth, however great job.

Why another one ?

A very long story, to be as short as possible I needed faster and more compact code to:

Test if the element match the criteria written as CSS selector.

At that time most frameworks/libraries only provided a similar approach, too slow for my needs:

Go through all matching elements and see if element is there.

Some time stolen to my main project and some extra sleepless nights allowed me to finally "close the circle" and publish a quite capable Event Manager that is now using NWMatcher to its full potential for event delegation (as was initially planned).

Is there something new ?

Sure there is. You may have not noticed yet, but as an extra to what standard selector engines offers, by coupling NWEvents and NWMatcher you get methods that let you solve the "onload" problem most times. Look here for more info on this new way to handle the problem: This is something like Behaviors, but events can be attached earlier, no need to wait "onload" and only one event is attached for each group of elements and future dynamically inserted elements if they match the group criteria (selector).

When I started this, there where few choices fast enough for my needs, one was the very basic getElementsBySelector() written by Simon Willison the other one was CSSQuery by Dean Edwards. After testing both engines I realized that speed was a big problem and should left all the goodies of Dean CSSQuery and just stay with the simpler one. Less CSS selectors compatibility but at least with Simon getElementBySelector() I could easily setup a proof of concept and see it working, slowly on the worst cases but still working.

The final touch up

In the last years I have been caught so much by the unobtrusive web programming and started to implement the "Event Delegation" pattern in the most common and raw way in Javascript. About mid 2007 this was working just well for most CSS2 selectors, but I wished a boost in performance and I wanted to have more CSS2 and newer CSS3 selector to be also available for event delegation. I asked for help to Peter Michaux. He patiently listened to my ideas, debated with me on that and provided me a first skeleton of compiled selectors.

Event Delegation applied to Javascript is the fastest and more scalable pattern for any type of Javascript application, from the smallest scriptlets to complex frameworks up to the biggest RIA applications. Web UI responsiveness can only be greatly improved if we can count on fast and stable events and delegates.

NWMatcher aims to be one of the building stones of this scenario and NWEvents is the door to event delegation using reliable events combined with fast and reliable selectors.

This is by no means the last word on this, my code can be improved both in syntax and speed, there are surely bugs still around that I will try to correct with help of testers.

Testing NWMatcher with and without caching

NWMatcher provides a way for the user to configure the state of it's internal caching system, ENABLED or DISABLED. Even if we tell NWMatcher to do caching, it will still do it's best to detect the DOM has changed by using Mutation Events. This is true on all browsers but IE, so the caching system is disabled by default on IE. You may enable it using setCache().

By default the cache is "enabled" on Firefox, Safari, Opera, and Konqueror, this gives the best results in speed still being able to be notified and flush the cache when the document changes.

The same TEST with different caching settings

NOTE:For the dynamic pages tests the "template.php" file has been slightly modified to do "appendChild" and "insertBefore" just after the end of each test iteration, so the number of nodes are different for each query.

Important details on how to use it

NWMatcher has been written with compatibility in mind. To achieve that goal I avoided to use too many native methods, this also due to the many bugs that affect the standard DOM methods especially on Internet Explorer (ex: getElementById, getElementsByTagName).

The singleton provides only four usable methos. They are:


    // return boolean true/false
    NW.Dom.match(element, selector);

    // return array of elements
    NW.Dom.select(selector, from);

    // enable cache, no return value
    NW.Dom.setCache(true);

    // flush cache, no return value
    NW.Dom.expireCache();

Of the four methods, you would probably just need to use two, the "select" and the "match" methods, respectively for getting collections or just checking a single element.

The caching can be set programmatically by calling:


    // pass true to enable or false to disable
    NW.Dom.setCache(false);

The current cache can be forced to expire by calling:


    // no return value
    NW.Dom.expireCache();

Objectives for this code:

Tested compatibility

Some testing have been done on different browsers and platform OS (Linux/Mac/Windows).
I haven't found browsers failing yet but I will keep the list updated with incoming info.

Bugs ?

Yes there are. Well hidden though, couldn't find them yet...


Diego Perini