Archive for February, 2009

Evaluating Javascript Performance

There’s a lot of factors that you have to take into account when you pick a javascript framework. Picking the right tool is a balance of developer familiarity, the task at hand, and performance.

Measuring a framework’s performance is tricky. The reality is that no benchmark will account for what your app will do in real life. Making the task harder is that each framework has different features, making a straight head-to-head comparison impossible. However, that doesn’t mean we don’t need to know the relative speed of different frameworks.

I found myself in that position recently. I attempted to gauge the relative speed of Mootools, JQuery, Prototype, and Appcelerator. The rational behind picking these four frameworks is that I understood them enough to create a simple test.

the benchmark

The bechmark that I wrote is a rails app and available on GitHub. The README describes what it does:

This pretty simple test attempts to measure the time it takes to load the framework and do some basic tasks.
The first is to load the page with the W3C css
selector
page
pre-loaded into a hidden div. It then dynamically loads in the Georgia 2008 Presidential election
results
, again in a hidden div.
Next it loads in the
Georgia 2008 Senate results and
attaches a
click event to all the red elements. Finally,
it loads in the Georgia 2008 election
summary.

All files are served from the local server to avoid mistimes due to network latency.

Because of the way Appcelerator works, instead of using a selector to attach an event, I’ve created
a different version of the “dynamic” html file with “on” expressions set for the red elements. I
feel this test is more fair, since there’s no reason to select through the dom when Appcelerator
processes each element by default.

This is a rails app, so you should just be able to download it, then run script/server.
Navigate to localhost:3000 and you’ll be good to go.

Feel free to fork and improve as you see fit.

results

I ran the benchmarks on my Windows XP vm, with 384MB of RAM running within VMWare Fusion on a 2.2GHz Macbook Pro. These are the times. Appcelerator is included twice. The first is an internal patched version. The second is the latest 2.2.1 release. Columns in Red indicate that an error occurred while running the test.

Test (all times in ms) Firefox Safari Chrome IE
Prototype
Framework Loaded in 80 359 224 31
DOM Loaded in 127 1567 155 109
Load Large File 247 79 164 141
Dynamic Large File 179 104 135 703
Crazy-Large File 3828 572 1363 985
Total 4493 2681 2042 1984
JQuery
Framework Loaded in 111 60 517 141
DOM Loaded in 58 10 28 31
Load Large File 234 198 249 563
Dynamic Large File 474 209 227 1187
Crazy-Large File 1055 861 2218 3922
Total 1968 1338 3240 5876
Mootools
Framework Loaded in 48 54 147 485
DOM Loaded in 45 11 44 62
Load Large File 319 142 190 3813
Dynamic Large File 275 170 124 2329
Crazy-Large File 1697 932 1293 24877
Total 2413 1310 1799 31598
Appcelerator (internal)
Framework Loaded in 190 234 timeout 281
DOM Loaded in 870 341 timeout 2485
Load Large File 1241 501 timeout 24237
Dynamic Large File 1086 578 timeout 31331
Crazy-Large File 20196 2772 timeout 595237
Total 23658 4426 timeout 653664
Appcelerator (2.2.1)
Framework Loaded in 343 425 timeout Error
DOM Loaded in 1067 748 timeout Error
Load Large File 3145 2053 timeout Error
Dynamic Large File 2420 1253 timeout Error
Crazy-Large File 17814 6780 timeout Error
Total 24841 11265 timeout Error

conclusions

Safari is incredibly fast. If all your users used Safari, the framework you use doesn’t really matter. I’m pretty surprised with how fast Prototype was in IE. It was the only one that was quicker in IE than in FF. Mootools and JQuery had similar performance, right up until it came time to load a very large file in IE. No framework was the clear winner on speed.

Hopefully this benchmark provides a little guidance on which framework to pick. If all you’re doing is catering to Safari users, feel free to go with something like Appcelerator. If you need to target IE users or the general web population, you can’t go wrong with Prototype, Mootools or JQuery, unless you’re loading in very large files, at which point Mootools is out. Otherwise, pick for which one you like better.

  • Share/Bookmark

StartupRiot 2009

Sonali and I have been working a project to make a light weight and hosted project management tool. We’re calling it SCMPLE and yesterday was our first pitch. You can checkout Our Slides.

For those that don’t know, Startup Riot gives startups like ours a forum to present and connect with like minded individuals. We’re barely out of the idea stage, but we still had a bunch of people come up and talk to us about our idea. Which rocked, because we were the second up and I wasn’t all that awake yet.

There wasn’t very much that didn’t rock about the event. Given that we’re pitching a Git based idea, I would have preferred to have not immediately followed the keynote by Chris Wanswrath of GitHub fame. He gave a great talk, has a very cool product, and is a super nice guy, so it’s hard to be upset about that. The overall message of “do what you’re passionate about” resonated strongly within the audience.

The pitches were surprisingly interesting. You’d think that watching 17 or so companies present in a row would get boring or repetitive, but neither happened. Even the bad pitches or unreadable slides were worthwhile because of the Backnoise, though it did go a little overboard.

The only real downside of StartupRiot is that I’ve had to switch to TweetDeck. Just met enough new folks to break the camel’s back with Hahlo.

As a presenter, I’ve got to thank Sanjay Parekh, not just for the main event, but all the free advice and help in getting ready for it. It was my first pitch out to an audience that didn’t know exactly what I was talking about. I also need to thank Scott Burkett and Jeff McConnell, who both gave some great guidance during the practice session.

Also as a presenter, I wouldn’t mind paying to present. The fees for StartupRiot really are nominal, given the value I obtained for it. If there is anything that will keep the event going, I’m all for it.

  • Share/Bookmark

Chaining Mootools Events Explained

There’s tons of doc out there explaining how to chain Mootools events, but very little of it really explains what’s really going on, why the code looks the way it does, and most importantly, how to get it to do what you want. This is my attempt to fill in the gap with Mootools 1.2.1.

Chaining

The basic problem is that the way people do transitions in javascript. Every transition library effectively just does something very fancy around setTimeout. This works well if you’re just sliding in an element, but if you want to slide out an element, then slide in another one, you get something that looks very weird, if you’re not careful. Transitions aren’t atomic functions. When the javascript interpreter hits a setTimeout in Transition A, it moves on to Transition B, and vice versa. Effectively they happen at the same time.

To get what you want, Mootools includes the Chain class. From the doc:

A Utility Class which executes functions one after another, with each function firing after completion of the previous. Its methods can be implemented with Class:implement into any Class, and it is currently implemented in Fx and Request. In Fx, for example, it is used to create custom, complex animations.

Chain is implemented by the Fx.Tween class. The Fx.Tween class is the class that allows you to transition between various style properties. This super simple example shows how to switch between background colors for the element with id="example1"(download mootools_chaining):

    var fx = new Fx.Tween($('example1'));
    fx.start('backgroundColor', 'red').chain(function() {
        this.start('backgroundColor', 'blue')
    }).chain(function() {
        this.start('backgroundColor', 'green')
    });

All I’m doing here is creating a tween on the element example1. Then I turn the background red, blue, and green (in that order).

Ok, that looks easy enough. But what if I want to do something more complex, such as fade out one element (example2_header1), and fade in another (example2_header2)? The first thought would be to do something like:

    // THE WRONG WAY TO DO IT!
    var fx = new Fx.Tween($('example2_header1'));
    fx.start('opacity', 0).chain(function() {
        this.set('display', 'none');
    }).chain(function() {
        $('example2_header2').setStyle('display', 'block');
    }).chain(function() {
        $('example2_header2').tween('opacity', 1);
    });

This example will never show the element example2_header2. To understand why this is, we need to look at the difference between the Fx.Tween.set and Fx.Tween.start methods.

Fx.Tween.set

set: function(property, now){
	if (arguments.length == 1){
		now = property;
		property = this.property || this.options.property;
	}
	this.render(this.element, property, now, this.options.unit);
	return this;
}

Fx.Tween.start

start: function(property, from, to){
	if (!this.check(arguments.callee, property, from, to)) return this;
	var args = Array.flatten(arguments);
	this.property = this.options.property || args.shift();
	var parsed = this.prepare(this.element, this.property, args);
	return this.parent(parsed.from, parsed.to);
}

Notice the difference in return. Fx.Tween.start calls into the Fx parent class, but Fx.Tween.set does not. The Fx.start method creates a timer, and when that completes, it calls the Fx.onComplete method:

onComplete: function(){
	this.fireEvent('complete', this.subject);
	if (!this.callChain()) this.fireEvent('chainComplete', this.subject);
},

Aha! This is why the second example fails. For non-fx type function calls, this.callChain() must be called manually. Thus, the code to get it all working is:

    var fx = new Fx.Tween($('example2_header1'));
        fx.start('opacity', 0).chain(function() {
            this.set('display', 'none');
            this.callChain();
        }).chain(function() {
            $('example2_header2').setStyle('display', 'block');
            this.callChain();
        }).chain(function() {
            $('example2_header2').tween('opacity', 1);
        });
    });

You can download the full working example (including the HTML around it).

  • Share/Bookmark

Moving On Up

WordPress is now the CMS for vijedi.net. Everything that I do on the site is recorded here in some way. It just made sense to have wordpress actually be at the top level directory.

I know this post isn’t very interesting, but I wanted to write something to see if my feeds still work.

  • Share/Bookmark

Nikon D60 First Shots at Kennesaw Mountain

Powered by Flickr Gallery
  • Share/Bookmark
Return top

About

This is my blog about programming. For random stuff, checkout my Twitter or Tumblr