March 25th, 2009
22 Comments

Rolling out Sly - The JavaScript Selector Engine

Finally, a new selector engine!

Sly is a turbocharged, cross-browser, library-agnostic JavaScript class for querying DOM documents using CSS3 selectors.

If you’re a code geek like me, you might want skip the details and go directly to the source, the speed tests or the specs.

Sly awesomeness:

  • Pure and powerful JavaScript matching algorithm for fast and accurate queries
  • Extra optimizations for frequently used selectors and latest browser features
  • Works uniformly in DOM documents, fragments or XML documents
  • Utility methods for matching and filtering of elements
  • Standalone selector parser to produce JavaScript Object representations
  • Customizable pseudo-classes, attribute operators and combinators
  • Just 3 kB! (minified and gzipped, 8 kB without gzip)
  • No dependencies on third-party JS libraries, but developers can override internal methods (like getAttribute) for seamless integration.
  • Code follows the MooTools philosophy, respecting strict standards, throwing no warnings and using meaningful variable names

Querying the DOM with Sly:

// Finds all odd rows in all tables
var rows = Sly.search('table td:odd');

// Finds all links with class "internal" and an attribute "href" starting with "#".
var links = Sly.search('a.internal[href^="#"]');

// Another notation is also possible, since Sly acts as a constructor
var snippets = Sly('pre.highlight.javascript > code').search();

// features is just one element, lists has all list items are siblings of features
var features = Sly.find('#features');
var lists = Sly.search('~ ul', body);

more examples and documentation.

Performance

But enough babbling: I know you just want speed and validity results. The following results were measured using a list of frequently used selectors, searching on a copy of yahoo.com, running in slickspeed.

Sly - Selector Performance


(See also the DOM fragment speed graph) If you are interested, run the various speed tests on your own system and post your results.

The adapted version of slickspeed also supports other test cases, like querying on a DOM fragment or an XML document. They make sure that Sly and other engines work the same in all environments.

If you want to know more, visit the repository at github, it holds the source, documentation and the test suite. The next post will give more technical details, what secrets can make this small script so blazing fast. Any feedback is welcome, keep the comments coming.

Keywords:
Share it: Stumble it!Digg This!del.icio.us (71 Posts: )

discussion by DISQUS 22 Comments

Please use the support forums for discussing the project, asking questions or posting bug-fixes!

Sort:
Comments 1 – 20 of 22:
  • reply
    Avatar
    timothymarshall 0 Point
    said 2 years ago (1 Point)

    I've integrated Sly into Deft, a new JavaScript framework. Check it out at deftjs.com.

    I haven't posted documentation or the API yet. Site is very very basic. Since It is not ready to be an RC, but rather just a sneak peek at what it will be.

  • reply
    Avatar
    Mic
    said 2 years ago (1 Point)

    Some libraries gave me a hard time to integrate with PURE v2 (a JS template engine).

    But with Sly it was smooth and easy.
    In addition, PURE is using heavily selectors. So thanks for the extra speed!

    You can see it running at: http://beebole.com/pure/versio...

  • reply
    Avatar
    said 2 years ago (1 Point)

    Implemented this in a JS framework i'm putting together. Will be hosted @ deftjs.com. And thanks again for the great code!

  • reply
    Avatar
    said 3 years ago (1 Point)

    Prototype on Sly is "3x faster"

    checkout this http://firejune.com/1398

  • reply
    Avatar
    digitarald Site Owner
    replied 3 years ago (1 Point)

    Nice and simple implementation, thanks a lot for sharing!

  • reply
    Avatar
    csuwldcat 60 Points
    said 3 years ago (1 Point)

    Is this a new thing for the Mootools lib or is that not the eventual point... Just wondering :)

  • reply
    Avatar
    Tim Lavelle
    said 3 years ago (1 Point)

    Very impressive script!!!
    I've been wanting a fast way to do this for ages!!

    w00t!

  • reply
    Avatar
    procyon
    said 3 years ago (1 Point)

    Impressive! Brilliant work Harald! When no one thought selector engines could be faster, you create Sly..damn fassstt, it's just crazy and the code is so beautiful.
    I hope to see Sly in Moo..and maybe in jQ, Dojo.. ;)
    Cheers :)

    Alexandre Rocha

  • reply
    Avatar
    Josh Powell 13 Points
    said 3 years ago (1 Point)

    Hey Harald, can you add straight up sizzle to your comparison, instead of jquery 1.3.2, or in addition to it?

  • reply
    Avatar
    fribirdz
    replied 3 years ago (1 Point)

    I agree this. could you add sizzle to your performance test?

  • reply
    Avatar
    said 3 years ago (1 Point)

    Quite great job!
    I can't wait to use it.
    Thanks

  • reply
    Avatar
    said 3 years ago (1 Point)

    Nice work, love it. Why haven't you rewritten the mootools selector engine yet? ;)

  • reply
    Avatar
    said 3 years ago (1 Point)

    Very nice work, briefly scanned the code and it looks great.

  • reply
    Avatar
    Rasmus Fløe 16 Points
    said 3 years ago (1 Point)

    Nice one, Harald!

    Shouldn't the browser list on the graph have been reversed?

    Let's see if this makes it into jQuery ;)

  • reply
    Avatar
    said 3 years ago (1 Point)

    Amazing! I plan to put this to use

  • reply
    Avatar
    said 3 years ago (1 Point)

    Yup, one of the main reasons Sly > all (in my view) is the beauty of its code.

    As usual, great work from Harald.

  • reply
    Avatar
    Matthias 4 Points
    said 3 years ago (1 Point)

    Looks amazing! Is this going to be integrated into mootools?

  • reply
    Avatar
    said 3 years ago (1 Point)

    This is totally awesome! Way to go!

  • reply
    Avatar
    fredrikc 0 Point
    said 3 years ago (1 Point)

    Did some testing, changed array.push(item) to array[array.length] = item; and got some love from Opera, the other browsers seems to handle both ways of doing at the same speed.

    Also did some changes in nth-child, added a check if state.positions.length was bigger than zero in that case the normal while, otherwise a very small while, it might be an speed-optimization but very small in that case.
    I put up a test-suite of my changes here: http://nalar.lc-solutions.se/S... (1 and 2 are both the same code just to show how random the results are)

  • reply
    Avatar
    digitarald Site Owner
    said 3 years ago (1 Point)

    I'm very happy that so many other code geeks, thinking like me, follow my journal!

Comments 1 – 20 of 22:

Post your comment

Please use the support forums for discussing the project, asking questions or posting bug-fixes!


Internet Consultant & Contractor

I'm available to combine forces with you and your team to find the most simple, elegant and convenient web solutions . I await your call.

If you just like my work and want to say Thank You, donate via PayPal or Amazon Wish List.

Developer Resources & Tools