Using Fireunit to analyze JavaScript code performance

Often times when coding one might pause to consider if one solution performs better than another — when they effectively do the same thing. When a toolkit is involved you might also have a trade-off between code brevity and plain old JavaScript to consider.

A helpful tool I use regularly is Fireunit, the Firebug add-on. It can be used for more than I’m going to show here, but for very quick tests to see how fast my code will run, I’ll pop open the console and try the code out there.

In this example, I’m just seeing which is faster at finding the head tag.

Here, I’m using dojo.query
dojo.query("head")[0];

What stands out is there are 8 individual calls, sure, each is tiny and only adds up to .5ms.

For comparison, we try the old fashioned way
document.getElementsByTagName("head")[0];

The native JavaScript is looking much faster, .144ms compared to .5ms.

Take note that all you need to do is pass fireunit.profile a function to test
fireunit.profile(function { ....do stuff....});
and the results are displayed directly in the console.

So what I learned was, using dojo.query for this very simple operation is slower than native code. I don’t doubt for a minute that a complex query would be faster than a plain JS alternative, but it did help make me conscious at least of testing code this way.

Another thing to highlight, if you run each test several times you see that after the first run, document.getElementsByTagName results get even better – over 20 times faster than the dojo.query code (which by the way doesn’t get faster in sequential runs).

Posted in Firebug, Fireunit, performance | 1 Comment

Cleaning up after your custom dojo widgets


The process of creating dojo widgets is one topic of discussion, but coding them so they can be destroyed well, without leaving anything unwanted or buggy behind, is another altogether. In many web apps you will want to call widget.destroy() after you are done with the widget. Here are some best practices I have adopted to help do this effectively.

To start, when a widget template is parsed and the object is created, all child widgets are added to an array called
dijit._Widget._supportingWidgets[]
and all dojoAttachEvents are added to
dijit._Widget._connects[]

When widgets are destroyed, these supportingWidgets are recursively deleted (from DOM) and all connections created via dojoAttachEvent are removed safely. This works great for things defined in templates, but when we add our own dojo.connects or create child widgets programatically, we have to be responsible for deleting the DOM and removing connections.

Remove DOM
To ensure the DOM is destroyed automatically, add it to ._supportingWidgets array. Example a custom rich-text editor:
this.smileyPalette = new ws.widget.SmileyPalette();
this._supportingWidgets.push(this.smileyPalette);

Remove connections
The easiest way to make this automatic, is to use the widget’s connect() method, which is the same as dojo.connect, except you don’t need the 3rd scope argument (this), and it will get added to the ._connects array. Example:
dojo.connect(this.smileyPalette, "onSmileyClicked", this, "insertSmiley");
becomes
this.connect(this.smileyPalette, "onSmileyClicked", "insertSmiley");
** note: this connection will be destroyed when the widget is destroyed. If the smiley palette was destroyed by something else we would have a problem. So it might make more sense to attach this event to the smiley palette widget itself:
this.smileyPalette.connect(this.smileyPalette, "onSmileyClicked", "insertSmiley");
Since the smileyPalette was a supporting widget of its parent widget, it will be torn-down correctly, and if the smileyPalette is ever destroyed independently of its parent, the connection will be cleaned up as well.

Final code:
this.smileyPalette = new ws.widget.SmileyPalette();
this._supportingWidgets.push(this.smileyPalette);
this.smileyPalette.startup();
this.smileyPalette.connect(this.smileyPalette, "onSmileyClicked", "insertSmiley");

Alternatively, you can add anything to your widgets inherited uninitialize function, which gets called when the widget’s destroy() function is called. It’s just a stub function in dijit._Widget, so you simply override it in your widget and do whatever needs to be done (delete DOM, disconnect events, etc… to tear it down cleanly.

Also, I recommend using this.subscribe instead of dojo.subscribe, inside widgets, so they will be automatically unsubscribed by the destroy function.

Cleaning up unused DOM is important to the health of your web app. Removing event listeners is important especially in regards to memory leaks. Using the methods described above will help keep things cleaner.

Posted in dijit, performance, _Widget | 1 Comment