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:
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:
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:
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.