MooTools, AJAX, DHTML and Performance

I first delved into javascript frameworks with Prototype, but I quickly realised that the Prototype+Script.aculo.us combination, even in Protocoluous or Protopackt form, was never going to work – it was just too slow.

I moved to MooTools, and for a while was pretty happy – load times were quicker, effects smoother.

But having recently tried to build sorting and filtering functionality into an HTML table of 200+ rows, I’ve been forced to take a closer look at how different browsers execute javascript, and at where the bottlenecks are. Here I’m going to promote a few best practices, largely via Julien LeComte at Yahoo.

Inserting new Elements

Working with the DOM in MooTools is a breeze – code like the following is a pleasure to write and to read:

var div = new Element(‘div’, {id:’example’}).addClass(‘example’).setHTML(‘Example Content’).injectAfer(‘previousElementID’);

However it’s worth noting that the Element class uses ‘document.createElement’, which is much more expensive than the alternative, albeit less readible innerHTML. Further, inject() and adopt() functions use appendChild() and are also thus very expensive. An it certainly feels like this effect is magnified when working with tables.

Changing Existing Elements

Working with with DOM can cause performance issues, but if the DOM element in question is not visible (display:none), or if the DOM element is ‘off-DOM’, you’ll acheive a performance gain.

Retrieving Values from the DOM

Retreiving values from the DOM is much more expensive than referencing a local variable:

// bad code
children.each(function(child) {
if (child.getText() == otherElement.getText()) alert(‘slow’);
});

// good code
var text = otherElement.getText();
children.each(function(child) {
if (child.getText() == text) alert(‘fast’);
});

Attaching Event Handlers

Attaching events is also very slow. To tackle this, instead of looping through multiple elements attaching events, attach the event handler to the parent, and within the handler detect which element has been clicked:

// bad code
children.each(function(child) {
child.addEvent(‘mousedown’, function () {
alert(child.getText());
}
});

// good code
parent.addEvent(‘mousedown’, function (e) {
var child = new Event(e).target;
alert(child.getText());
}

By applying these ideas, I was able to cut the processing time of loading a table by more than 70%, and hopefully you can benefit too.

"solid ability in all aspects of creating a successful user interface"

Denise Ross
UX Designer Barclays Bank PLC

Think we may be able to help you? Why not start a conversation - chances are, you'll go away with some new ideas and knowledge.