The Passing of a Giant

Michael Jackson, an icon for an era, passed away yesterday at an overly young age of 50. His era was my era. I was in high school when Thriller came out. The album was pure electricity and a defining musical moment for a lot of kids. I’m still a big fan of 80s music, and this album was a lion.

It was sad to watch Michael descend into freak show status. He wasn’t ready for his celebrity status, and I’m sure he had too many handlers doing whatever they could to keep their gravy train going, leading to his decline. Michael became the human equivalent of a factory farm hog – fed, doped and bringing home the bacon for his owners.

So rest in peace, Michael. And remember, don’t stop ’til you get enough.

Rounding Error

A few months ago, I ran some performance comparisons of various JavaScript selector engines using Slickspeed. My intent was to validate claims made by the ExtJS team as to why they didn’t use the Sizzle selector engine in Ext Core.

Ext Core has now gone final, so I wanted to re-run my tests. But there was also some news on the browser front: Apple released Safari 4 and Google dropped Chrome 2. Being the geek I am, I had to try them out. My Slickspeed test was the perfect candidate for seeing what Safari 4 and Chrome 2 could do.

In my prior post, I said developers should be bowing at the throne of Google for Chrome and its pack-leading JavaScript performance. That crown has now been abdicated. Safari 4 and Chrome 2 are leaps and bounds ahead of everything else on Slickspeed.

Here are the details on Safari 4:

  • Prototype: - 9ms
  • Dojo: - 3ms
  • JQuery: - 4ms
  • ExtCore: - 19ms
  • Sizzle: - 2ms

safari4

Safari 4 didn’t get along well with SnagIt, so I was only able to capture the bottom of the results output. Here are the results for Chrome 2:

  • Prototype: - 13ms
  • Dojo: - 4ms
  • JQuery: - 2ms
  • ExtCore: - 41ms
  • Sizzle: - 1ms

chrome2

This is simply stupendous. The performance of JQuery turns into a rounding error in both these browsers. As a basis of comparison, here are the prior results for Chrome 1:

  • Prototype: - 13ms
  • Dojo: - 7ms
  • JQuery: - 8ms
  • ExtCore: - 13ms
  • Sizzle: - 8ms

So what conclusions can we draw?

  1. Choice of JavaScript engine becomes irrelevant with any of these two WebKit based browsers. They all fly, even lowly Prototype.
  2. Ext, LLC, screwed the pooch in not using Sizzle for the selector engine in ExtCore. It would have been a better investment in them adopting Sizzle and working to improve it rather than blazing their own trail. The difference in Chrome 2 between Sizzle and ExtCore is staggering: 1ms in Sizzle vs 41ms for ExtCore.
  3. The latest and greatest from Microsoft (IE8) starts to look absolutely pathetic compared to the competition. Microsoft should be ashamed of themselves for having their asses so soundly handed to them on such a critical piece of infrastructure as the browser. Whether it is due to their outdated opinions on open source, or that they can no longer attract top talent, Microsoft is proving to not even be a contender in the JavaScript performance race.
  4. Both Apple and Google use WebKit as the basis for their mobile offerings (iPhone and Android). The sheer power of WebKit is going to offer both these platforms outstanding opportunities for rich browser-based applications. It is clear why neither platform cares much about Flash or Silverlight: the don’t need them.

Charity Overload

One of resolutions for the year was to give $100 a month to a different charity each month throughout the year. I’ve been on a pretty good roll so far this year, hitting five charities I’ve felt good about giving to. But there is now a kink in my plan.

I’ve discovered giving money to a charity is like giving crack cocaine to an addict. My snailmail box is literally overflowing with solicitations for additional donations. There is always a new campaign where they need money now. Worse, it is clear some of my charities shared my name with other charities, because I’m now getting bombarded with solicitations from charities I have never heard of.

So my naive approach of picking a differently charity each month is not a sustainable objective if I don’t want to use a handcart when I go to the mailbox. I realize the tight economic times have made a lot of charities have to work harder for their contributions, but I’m honestly shocked and offended by the quantity of garbage in my mail that results from a simple $100 contribution.

So going forward, I’m going to take a simpler, less diverse route. I’ll continue to give $100 a month, but it will only go to a singe charity: Médecins Sans Frontières. They were my first of the year, and are still my favorite. I’ll make an exception for Toys for Tots at Christmas, but otherwise, I’ll be focusing on MSF.

Catchup

The last two weeks have basically gone by in a blur, so I finally decided to squeeze in some time for an update. At Orange Leap, we’ve been running at warp 11 putting the finishing touches on v1.0 of our product. I’ve been up to my neck in the bowels of Spring Security and attempting to integrate it with CAS and our LDAP server for single sign-on. It has been an absolute beat-down trying to get it all together, and I’ve developed a strong love-hate relationship Spring Security. It makes the simple stuff possible and the hard stuff really hard.

This past weekend, Dallas hosted the first ever Big (D)esign Conference. Organization was a bit rough around the edges, but the conference really rocked. I don’t usually hang much with the artsy design folks, even though it is something that interests me. This was like a breath of fresh air after too much time immersed in hairy backend coding. I met a lot of new Twitter friends and came away with some good ideas. Hopefully I can start back in on some frontend work in the coming weeks to try and apply it.

Some cool tech has dropped that I really want to find some time to get familiar with. Microsoft went live with Bing today, and it looks pretty cool so far. Adobe also dropped the first beta of Flash Builder 4 over on Adobe Labs. I’ve been having a lot of fun with Flex, but need to backburner it until end of June. I also signed up with Ribbit. It looks pretty awesome and is in the queue for brain cycles after I get comfortable with Flex. And I still want to find time to get deeper into Groovy.

Finally, Dallas Tech Fest is just around the corner and I’ve still got a lot of work to do on my presentation. It has been a struggle finding quality time to work at home. Zoe is has decided the best place to watch Elmo is on my lap at my computer, so I have to sneak in work at bath time or after she’s asleep.

(Ext.)Direct Miss

One of the biggest announcements from last month’s ExtJS Conference was the new Ext.Direct functionality in ExtJS 3.0. My criticism at the time was that there was a lot of smoke, but no fire. Almost every session mentioned it in some way or another, but they weren’t producing any enterprise-worthy server code showing how it is implemented.

Now, a month later, more details are starting to emerge, including implementations for various technologies. I sat down yesterday morning intending to take a look at the server side code in the Ext.Direct Pack; in particular the .NET and Java implementations. I was pretty disappointed with what I saw.

To understand my disappointment, you need to understand a bit of history around what Ext.Direct is attempting to do. Ext.Direct is going to be an RPC layer that exposes stub objects on the client JavaScript side that remotes the method calls to the server using JSON (or POST parameters). The protocol definition is designed to be technology-agnostic and easy to implement. In implementation, it would be the near-equivalent of DWR, except it would also run on PHP, C#, Ruby, etc…

Since I’m familiar with CORBA, RMI, SOAP and WCF, I approached Ext.Direct with a more critical eye. The biggest glaring hole in Ext.Direct is the parameter passing. Let’s take a look at a couple examples to demonstrate the problem. All the examples will assume a Java backend, and the service we’ll expose is the PersonService. I’ll work from the interface, since we don’t care about the implementation details:

public interface PersonService {
 
}

Easy

We’ll add a method to PersonService to demonstrate the simplest scenario:

public int getPersonCount();

The payload from Ext.Direct would look something like this:

{ "action":"PersonService",
   "method":"getPersonCount",
   "data":[],
   "type":"rpc",
   "tid":2}

This is the absolute easiest method to deal with. The operation takes no parameters, and the return value is a primitive. Ext.Direct can deal with this easily, but so could any AJAX library, so no secret sauce here.

Object

One of the key advantages to an RPC protocol is the ability to pass Objects. Well complicate things a bit by adding the following method to the PersonService:

public Person getPerson(int id);

For our example, we’ll assume the Person class looks like this. I’m not including setters/getters to try and keep it short:

public class Person {
  private int id;
  private String name;
  private int age;
  private Date birthDate;
}

In the method I added above, the JSON payload from Ext.Direct stays pretty simple:

{ "action":"PersonService",
   "method":"getPerson",
   "data":[1],
   "type":"rpc",
   "tid":2}

This should return the Person with the ID of 1, and depends on the server code to correctly serialize the Person object to JSON.

Harder

Now let’s make things painful. I’m going to include a method to add a Person.

public void addPerson(Person person);

This is where the wheels fly off of Ext.Direct. Since the protocol specifies the data element as an array, I’m not clear on how Ext.Direct would deal with this from the client side. Every example so far works with primitives as parameters, so I haven’t determined what it would do with a Person.

Ext.Direct would be much happier if I defined the addPerson method like this:

public void addPerson(int id, String name,int age, Date birthdate);

Then, the JSON payload would look like this:

{ "action":"PersonService",
   "method":"addPerson",
   "data":[1,"John Doe", 25, "Sun May 01 1985 00:00:00 GMT-0500 (Central Daylight Time)"],
   "type":"rpc",
   "tid":3}

Even in this “happy path” scenario for dealing with an object, your server-side implementation would need to be able to correctly deserialize the stringified javascript date object, which is not anything the current implementations handle.

The protocol specification states that the data element can also be a JSON object with named parameters, but it is not supported in the first implementation. This is going to be absolutely critical if Ext.Direct is going to evolve into a real RPC protocol. For example, using a JSON object for the data element in the above example would result in a JSON payload like this:

{ "action":"PersonService",
   "method":"addPerson",
   "data": {id: 1,
           name: "John Doe", 
           age: 25, 
           birthdate: "Sun May 01 1985 00:00:00 GMT-0500 (Central Daylight Time)"},
   "type":"rpc",
   "tid":3}

This would at least allow the server code a means to try and instantiate an instance of the Person object, as long as the server code is implemented in a language that allows for reflection of the Object.

My grief with Ext.Direct is that correctly implementing the server-side code to support the specification is a non-trivial endeavor. One big piece missing is the metadata. In other RPC mechanisms, there is strongly-typed metadata which can be used to create the stubs. For example, CORBA has IDL and SOAP has WSDL.

Ext.Direct is missing a metadata layer to facilitate the passing of Object values. It is going to be difficult to implement a complete server-side stack to handle the permutations that will arise. Developers will either need to dumb-down the exposed services to handle the limitations of Ext.Direct, or else they will end up doing a lot of custom work on top of the server side implementation to handle the type coercion.

I’m still not convinced Ext.Direct is the right path for ExtJS to be barking down. There are already established, tested protocols for handling RPC via JavaScript (DRW, WCF), and ExtJS already works quite well with basic AJAX over the HTTP protocol. Ext.Direct is adding a level of complexity to ExtJS which could easily turn into a rabbit hole that sucks up all their time. I would prefer they focus their precious development hours on the client library and leave the communication layers decisions to us. RPC is a complicated problem with a lot of history around it, and there is no reason for them to try and invent a new wheel in this space.

Flexible Spring

As I mentioned in my prior post, I’ve been going through the great Flex in a Week from Adobe. I finally hit Day 3 and had a need to play with BlazeDS for the second lesson. Being a fan of the Spring Framework, I decided to use the recently released Spring Blaze DS Integration 1.0rc1 (Spring-Flex). This ended up turning in to a bigger beatdown than I expected, for several reasons.

I really wanted to use the Spring-Flex integration because I like the annotation-driven dependency injection option that Spring brings to the table. Unfortunately, I could not find a single comprehensive document or example showing how to setup a project from end-to-end using Flex and Spring-Flex. I started with my Spring template project, adding in the BlazeDS dependencies and configuration. I then stripped out the stuff I didn’t care about for this example. Then I went digging through the various reference guides and blog posts trying to figure out the correct configuration I needed on both the Java and Flex side.

After about three days of hair pulling, the pieces finally started to fall in to place. Once I understood the configuration, it became a breeze to configure services to be exposed by Spring-Flex and to call those services from Flex via a RemoteObject. I’ve linked the complete Java project and Flex project archive below:

Spring-Flex Project

Flexbuilder Project Archive

There is a README.txt file in the root of the Java project directory that walks through the setup. This project is configured to talk to a MySQL database using an iBatis DAO layer and includes the setup scripts, all run from Ant. The build file also makes use of Ivy to grab dependencies, thus reducing the number of jars I have to include.

The Flex project is configured to talk to the exposed employeeService on localhost, so you’ll need to change the configuration of the RemoteObject if you want to point to a different destination.

Here are some of my lessons learned that will hopefully help others:

#1: Life is easier if you keep BlazeDS’s services-config.xml file in the default location: WEB-INF/flex/services-config.xml. The version of this file that comes with the BlazeDS turnkey download has a small problem. It does not specify default channels, which is what FlexBuilder will use to figure out what is going on. Look at the version I have in the Java file and notice at the top:

<services>
  <default-channels>
    <channel ref="my-amf" />
  </default-channels>
</services>

You’ll want this in your services-config.xml file if you plan on specifying an application server in FlexBuilder.

#2: And on the subject of application servers, you actually don’t even need to specify the server technology. I built my solution as a standalone Flex project with a standalone Java project and had the two talking together without a problem.

The secret to making it work is in how you configure the RemoteObject in FlexBuilder. Here is the configuration for my RemoteObject:

<mx:RemoteObject id="employeeRO" 
  destination="employeeService" 
  showBusyCursor="true"
  fault="handleFault(event)">
  <mx:channelSet>
    <mx:ChannelSet>
      <mx:AMFChannel id="amf" uri="http://localhost:8080/flex/messagebroker/amf"/>
    </mx:ChannelSet>
  </mx:channelSet>
  <mx:method name="getEmployees" result="allEmployeesHandler(event)"/>
  <mx:method name="doCreate" result="employeeHandler(event)"/>
  <mx:method name="doUpdate" result="employeeHandler(event)"/>
  <mx:method name="doDelete" result="employeeDeleteHandler(event)"/>
</mx:RemoteObject>

Specifying the ChannelSet enables you to take control of where the RemoteObject is binding to instead of relying of FlexBuilder magic. Just change the URI to point to the correct location.

There is one little catch. You need to set the FlexBuilder build output directory to Tomcat’s webapps/flex directory (after you have deployed the war file), or you’ll get a security exception about breaking out of the sandbox. I’m guessing that the flex file is looking for the services-config.xml file to figure out what it is supposed to do, and if it is not in the correct directory relative to the SWF file, your application will barf. So deploy the flex.war file from the Java project first, then play with the flex half of it.

#3: Once you have the dependencies sorted out, configuring the Flex broker is literally a one-line configuration option. Check out web/WEB-INF/flexDispatch-servlet.xml in the Java project and notice this line:

<flex:message-broker />

That’s all you need. Really. This one line of config uses “sensible defaults” to initialize BlazeDS. It will read services-config.xml from the default location (see tip #1) and setup the endpoints for you based on the configuration.

#4: I’m a fan of annotation-driven configuration for Spring, and Spring-Flex does not disappoint. Here is the implementation of the EmployeeService class:

@Service("employeeService")
@RemotingDestination
public class EmployeeServiceImpl implements EmployeeService {
 
    @Autowired
    private EmployeeDao employeeDao;
 
    @RemotingInclude
    public List<Employee> getEmployees() {
        return employeeDao.getEmployees();
    }
 
    @RemotingInclude
    public Employee getEmployee(String id) {
        return employeeDao.getEmployee(id);
    }
 
    @RemotingInclude
    public List<Employee> getEmployeesByDepartment(String department) {
        return employeeDao.getEmployeesByDepartment(department);
    }
 
    @RemotingInclude
    public void doCreate(Employee employee) {
        employeeDao.createEmployee(employee);
    }
 
    @RemotingInclude
    public void doUpdate(Employee employee) {
        employeeDao.updateEmployee(employee);
    }
 
    @RemotingInclude
    public void doDelete(Employee employee) {
        employeeDao.deleteEmployee( employee.getId() );
    }
}

The top @RemotingDestination tells Spring-Flex this is a service that is going to be exposed via BlazeDS. You can provide an optional parameter specifying which channels to use, if you have several configured. Then, each method you want to expose is annotated with the @RemotingInclude annotation. Methods that should not be exposed can be annotated with the @RemotingExclude annotation.

So if you’re following along with Flex in a Week, or have just been trying to get Spring-Flex up and talking to a Flex application, give the demo a try and look over the source code. This corresponds to the second video of Flex in a Week, Day 3. I wish I would have known some of these things starting out, so hopefully I can save other people some time.

Flex in a Week

One of my unexpected take-aways from the ExtJS conference last month was that I need to start looking at Flex again. This isn’t necessarily for the Flex framework itself, but because of AIR. I’ve started to see a lot more AIR applications popping up, and my Twitter client (Twhirl) is even AIR based. ExtJS with AIR makes for an extremely powerful combination.

So to build a foundation for AIR, I decided to learn Flex. After a strong year of JavaScript, Flex starts to make a lot more sense from a syntax standpoint. And ironically, the best way I’ve found to learn Flex is free: Flex in a Week.

Adobe has produced a truly outstanding series of video training classes for Flex. Although it is structured as five days worth of materials, I’m only getting through half a course each day due to quiet time constraints with a two-year old in the house. I have been very impressed with the quality and level of detail. The videos aren’t full of fluff and get quickly to code. There are exercises interspersed with the training videos, but I’ve passed over them, opting instead to follow along with the videos.

The only downfall to my choice to follow the videos instead of the exercises is that Adobe didn’t make it easy to find some of the supporting pieces you need to follow the videos. For example, there is an XML data file called employees.xml used for a lot of the code in the videos that is nowhere to be found. Ultimately, I found a CSV version of the data file in an AIR Sample, along with the images used for building the employee directory application.

In the interest of helping out others who start on Flex in a Week, here are the supporting files necessary for following along with the code. I’ve only finished the second day, so I’ll try and add any additional parts I find missing.

  • employees.xml - the XML data file with the employee information (right-click to save it)
  • headshot images - the thumbnail images for the directory, both normal and small sized

I’m hoping to finish up the tutorial this week and jump into more complex things with Flex. I’ve been very impressed so far, although not enough to eat crow yet on my negativity towards Flash in general.

What about Flex books? I picked up Programming Flex 3: The Comprehensive Guide to Creating Rich Internet Applications with Adobe Flex and it has been a total disappointment. The book is very poorly structured and it jumps all over the place without a coherent plan. It swings between excessive detail of the Flash engine, followed by trivial, poorly explained examples of the Flex widgets. I may find value in it later as a reference, but am dumping it for now.

I did pick up another book that I really like a lot: Learning Flex 3: Getting up to Speed with Rich Internet Applications (Adobe Developer Library). This one is well structured and gets to the things I’m interested in, not the nitty-gritty details of the Flash player. I would recommend this one for anyone who is at a similar point in their Flex learning experience.

Abel and Ready

This is the story of Abel, a hard-working, dedicated Java developer. One night, after a hair-pulling coding session with Spring Security, Abel was visited by the Ghost of Java. “Abel, you have been extremely dedicated to me,” said the Ghost, “and for that, you will be rewarded.” “You will be visited by three ladies of the night as a reward for your years of sweat and turmoil hacking me,” the Ghost continued.

Two thoughts quickly raced through Abel’s mind. First, being a Java developer, it meant he would actually have to shave and shower for the next three days. Second, being a dedicated Java developer, three ladies in three nights might be a bigger task than he could handle. But throwing caution to the wind, he told the Ghost of Java he was up to the task, although he mentioned he would have preferred Java 7.

On the first night, a rather mature woman, slightly past her prime, showed up at his door. She was perfectly dressed in a revealing blue dress, but her exquisite makeup was not up to the task of concealing her sags and wrinkles. She said her name was IBM and that she would show Abel a good time. What she lacked in looks she made up for in conversation. She treated Abel like the center of the universe and was always ready with a supportive comment or another glass of expensive champagne. Abel was somewhat satisfied with the happy ending to the evening. It wasn’t spectacular but IBM made sure he knew it was all about him.

Abel’s second night took an abrupt turn for the worse when the next lady walked in. Looking like a crack whore in a thousand-dollar mini skirt, Abel’s new date introduced herself as Oracle. Upon seeing her, Abel’s first reaction was to put his hand on his wallet. Unlike his prior date, Oracle made clear the world revolved around her. She talked all night about the great many tricks she could do for Abel, but all for a price. Abel was thoroughly distracted from the happy ending between trying to keep an eye on his wallet and worrying he might catch something from his new date.

On the third night, Abel hid in his closet, fearing a repeat of the second night. Instead, he was pleasantly surprised when a curvaceous, girl-next-door redhead came in to his room and introduced herself as Microsoft. Although not much for conversation, Microsoft had curves in all the right places and not a wrinkle to be found. Abel got a chuckle over how she liked spinning in the flowers and talking about her MySpace page. The happy ending was very easy; so easy in fact that he wondered how he would ever be satisfied with anything more complicated again.

Abel’s plight is one that many Java developers have run through their head this past week as news made it out that Oracle had purchased Sun Microsystems. IBM, the aging monstrosity it is, would have killed Java through neglect. Oracle, the crack whore of software, will possibly kill Java through trying to monetize (read “nickel and dime”) the development community to death. And then we have Microsoft, with C# 3.5, whispering sweet nothings in developers ears.

So what is a Java developer to do? I fretted over this most the week so that I could be more rational when I put the pen to it. IBM owning Java would not be pleasant due to IBM always managing to be five years behind the technology curve. While that might be popular with large enterprises, it does nothing to please the alpha geeks that made Java what it is today. We can joke about Java being the new Cobol. IBM would have guaranteed it.

About the only worse possibility would be for Oracle to own Java, which is where we find ourselves today. Whereas Sun was an engineering company, Oracle is a sales company, and software developers strongly prefer dealing with the former. I have no doubt that Oracle will try to find a way to monetize Java, to the detriment of the community.

Finally, we have the wildcard Microsoft. C# is not much a leap for a Java developer. And having sampled their forbidden fruit, there is definitely something to be appreciated. Microsoft would be more than happy to offer disenfranchised Java developers a new home.

But ultimately, there is another option, as Rod Johnson pointed out. Through the open source community, Java has grown beyond any one vendor. Yes, Oracle may try and stifle this community through a future Java release under a restrictive license which breaks compatibility with open source Java, but that would only cement their irrelevance.

Oracle’s ownership of Java means that the fate of Java is now in the community’s hands and not a vendor’s. There will not be much love for Oracle with Java developers, so I expect the next version of Java anyone cares about to called JDK 7 and not Java 7. And it will be a true, open effort of dedicated developers and the Java ecosystem they have grown. So as tempting as it is to cave in to C#, I’m going to stick with Java for now and see where we can take this.

April: Going Direct

My ongoing saga of charitable giving stays on a humanitarian path for April. Although I strongly considered giving more to two of my favorite previous charities, I decided to try something different. So for April, my $100 goes to Direct Relief International.

DRI provides worldwide humanitarian assistance to people in need, including inside the United States. This keeps a theme going I created with a donation to MSF in January. Based on their rating with Charity Navigator, I’m confident my $100 donation to DRI will be put to good use helping people.

Slick Speed

One of the big questions that people have had about ExtCore is why didn’t it make use of the Sizzle selector engine. That was one of the questions I wanted to get answered at the Ext Conference last week, and I managed to pin down one of the core developers to get an answer. Their opinion was that Sizzle is too large and too slow. I don’t really care about the size aspect. They all tend to pack down into the 25K range, but I was interested in the speed comment. Like a lot of folks, I was led to believe that Sizzle had a lot of, well, sizzle. So in the interest of getting to the bottom of the story, I did a little unscientific testing of my own using Slickspeed, which tests selector engine performance.

I grabbed the latest of the main libraries: ExtCore (beta1), JQuery 1.3.2, Dojo Core 1.3.0, Prototype 1.6.0.3 and the Sizzle engine by itself. I ran Sizzle by itself because although JQuery uses Sizzle, the version of Sizzle in JQuery 1.3.2 is 0.93 while the current version on the Sizzle website is version 1.0. I used the latest version of Slickspeed and made three runs in IE8, Firefox 3.0.8 and Chrome 1.0.154.3. Yes, I disabled Firebug in Firefox. My dev desktop is a rather beefy Windows Vista 64-bit machine with a quad-core 2.66ghz CPU and 8GB of RAM. I did a complete page refresh between runs to start relatively clean. I was going to relaunch the browser between runs, but it ended up not making much of a difference.

First up was the latest and greatest from Microsoft, Internet Explorer 8.

  • Prototype: 440ms
  • Dojo: 61ms
  • JQuery: 48ms
  • ExtCore: 80ms
  • Sizzle: 46ms

ie8

The image shows the results from the last run. I was actually surprised that IE8 did reasonably well. One thing is clear, friends don’t let friends use Prototype with Internet Explorer.

Firefox was a slightly different story. The selector engine in Prototype still got its clock cleaned, and ExtCore swapped around with JQuery and Sizzle:

  • Prototype: 145ms
  • Dojo: 64ms
  • JQuery: 77ms
  • ExtCore: 49ms
  • Sizzle: 71ms

ff3

It was interesting both Sizzle implementations slow down in Firefox. I would wager that the Sizzle folks made a conscious decision to optimize the core selector engine for the most widely used browser (Internet Explorer). ExtCore leaps ahead with Firefox 3, while Dojo is still pretty consistently finishing in the middle. Oh, and friends don’t let friends use Prototype with Firefox either.

Chrome is an absolutely game-changing stunner of a browser. Based on the selector benchmarks, the developers for all these engines should be offering to have children for the Chrome developers:

  • Prototype: 13ms
  • Dojo: 7ms
  • JQuery: 8ms
  • ExtCore: 13ms
  • Sizzle: 8ms

chrome

Even lowly Prototype with Chrome makes any of the other libraries running in Firefox look like they’re standing still. Chrome is simply ungodly fast with all them. ExtCore could probably still use some tweaking, but we’re talking about a 7ms delta between the fastest and slowest.

So the Ext team’s claims for Sizzle being slower are only partially true. Sizzle appears to be faster in Internet Explorer, while the story flips around in Firefox where ExtCore is faster. All of them, even Prototype, are fast in Chrome. Pray for the day when Chrome takes over the world. Until that time, It looks like all them (Dojo, JQuery/Sizzle, ExtCore) are good in IE and Firefox, with the nod going to JQuery/Sizzle for Internet Explorer, the browser market share leader. And you really, really don’t want to use Prototype until all your clients have moved to a modern browser with native selector engines, or Chrome.

One glaring omission is that I didn’t test with IE7 or IE6. Using either of those browsers is also on my “friends don’t let friends…” list. It would be safe to say that they would both be slower. As I don’t have either installed on any of my computers, I would be happy to add an update for anyone who wants to run the tests themselves.

The Ext team earns some slack in their Internet Explorer performance as they are only a beta compared to the others. I’ll rerun the test again when ExtCore goes GA. And on a final note, here is the config.ini file for Slickspeed in case anyone wants to try the benchmark themselves, or you can grab the whole Slickspeed install with the selector engines configured.