Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

Dojo 1.3b3 Is Out

New Dojo hotness is about to land, and you can get your very own sneak-peek by grabbing one of the beta builds, or if you're a DOM-and-progressive-enhancement-only kinda person, you can grab only dojo.js.

So why should you be switching to Dojo or upgrading to 1.3? You can dig through the nearly 500 fixed bugs or the tentative release notes yourself, but broadly speaking, we've hit all of our major stated targets for 1.3: IE 8 compatibility, major performance improvements throughout the whole system, and enhancements that make the APIs you already know that much more powerful and useful. I don't want to get into specifics since Pete's release announcement will include much more detail, but I'll outline some of the changes to just the CSS query engine since that's the system I worked on most for this release (continued after the jump).

As you may know, Dojo's CSS query engine has always been wicked fast. Indeed, our original design target for doing CSS queries was that we wouldn't do an engine until we could be sure that it would be so fast that using it wouldn't slow down applications. Release after release, the query engine in Dojo has continued to improve, consistently beating all the other major toolkits, particularly on queries that get a lot of heavy use by Dojo developers. The world is changing, though, and over the Christmas break, I spent some time upgrading dojo.query to take advantage of the changes in browser landscape. For 1.3, my goal was to remove the XPath branch from the system and re-enable QSA in a robust way. The motivators were:

  1. Firefox 3.0's days are numbered. Since the DOM branch has been used on WebKit-based browsers for some time (it has been shown to be faster than XPath over the HTML DOM in tests), and since querySelectorAll is becoming available on IE 8, FF 3.1 3.5, and is now usable on WebKit browsers, the only customer for the XPath branch was FIrefox 3.0. With the imminent release of Firefox 3.1 3.5, it stops making sense to cart around a second selector engine target for the query compiler. The win is that we get to keep the speed for selectors that can be run through QSA, and since we drop the XPath branch, the core is both smaller and we have more room in our "byte budget" to optimize the DOM branch further.
  2. querySelectorAll is nearly usable. As has been noted elsewhere, querySelectorAll is good but fatally mis-designed for the rooted-query case. As a result of this and many, many, many QSA bugs on various browsers (yes you, IE 8) and gaps in CSS3 selector support, determining when to run a query via QSA and when to defer to the DOM branch isn't actually straightforward. Engines like Sizzle try to detect query failure and re-run on DOM, but that leads to serious performance deficiencies on browsers with half-hearted QSA implementations. It's also not accurate since silent errors are, well, silent. Enabling QSA, then, requires both a lot of work to handle rooted queries as well as feature and bug detection code to work around query engine differences.
  3. Portability. The new selector engine is affectionately named "Acme" (aka, "query.js") to indicate how generic it is. The engine is 100% stand-alone and can be integrated into other toolkits without much work at all. This is made possible thanks to some build-system magic in Dojo which keeps us from duplicating any functionality and by careful and judicious use of Dojo Core features. query.js can be used stand-alone without any extra work.
  4. Better infix operator handling could make things faster. Instead of using regular expressions to parse CSS selectors, Dojo's query engine generates an AST-like structure that represents a query. This system has always allowed us to have great visibility into what parts to optimize and how, but with 1.3 the AST generator now changes the way that infix operators (">", "~", and "+") are tokenized, making it possible to avoid inefficient queries which are then mostly thrown away and to skip error prone look-ahead code. This class of changes lead to huge speed wins.

I won't cite specific performance numbers here since, as I've noted in the past, query engines are a commodity. That's part of the reason we called the new engine "Acme". Fast enough is fast enough, and the bottlenecks are elsewhere in toolkits today. I'm proud that the new engine sets a high water mark for performance, and I encourage other query engine maintainers to look through query.js and adopt the approaches we've taken to achieve eye-popping aggregate performance across different browsers and types of queries. The code is clean and commented to the hilt with notes about overall design and specific implementation decisions. I'm also happy to answer questions that other engine authors have.

Acme is just one - and not nearly the biggest - reason that Dojo 1.3 is an outstanding release. I'll post more about some of the things I'm most excited about when 1.3 final is announced, but until then, I again encourage you to start working with the beta. While you're at it, you might also want to check out plugd, drails, Dojango, and Persevere. They're making it easier and faster to build great apps with Dojo and might save you tons of time.

Pete, Bill, Dustin, Becky, Adam, Kris, James, Bryan, Sam, Nikolai, Wolfram, Neil, Dylan, Tom, Chris (and you too, Chris), Tobias, Shane, Cougar, Jared, Doug, Josh, Bob, Roberto, and the rest of the Dojo community have a lot to be proud of with 1.3. Nice work, everyone!