prototype: IE and the cost of Element.extend()

By crisp on Thursday 9 August 2007 00:35
Categories: Browsers, Javascript, Views: 10.652

It seems that prototype like YUI is more and more moving towards code purity and are neglecting performance. I noticed this recently when I was benchmarking my own getElementsByClassName function and comparing it to the established javascript libraries that also support this functionality.

It is evident that such a function should squeeze every millisecond off of it's execution time since it will be used on large documents. It should branch wherever necessary to use the most efficient possible way using native support or XPath when available.

Fortunately in the case of getElementsByClassName prototype does use XPath when available (but does not yet consider native support for it as is the case in Gran Paradiso) but that leaves us with one of the most-used browsers in the world: Internet Explorer.

Whenever an element is targetted using prototype in IE prototype handsomly extends some usefull methods and properties to the element object which is quite practical but comes with a cost. When using getElementsByClassName that cost is even higher because basically at the first execution all elements in the document will be extended, even when they are not selected in the end-result.

How come? Well, basically prototype's getElementsByClassName will first select every element in the document (there is no parameter to only target specific elements) and than call the hasClassName function on the element. The first line of this function is:
if (!(element = $(element))) return;

And what does the $ function (one of the most obscure functionnames in the world) do? Right: Element.extend(element).

The common argument against this issue is to use $$ (an even more obscure functionname) which can take a CSS-like selector syntax as an argument, e.g. $$('.test'). Sure enough this syntax will in IE only extend those elements which are in the final resultset, but even then when the resultset is quite large this will cost you.

The main problem is that in most cases you don't really need those extensions to the element object, but there is no way to turn this feature off in prototype. Although I generally feel that this will give IE-users what they deserve for using such a backwards browser I think this is poor engineering.

I wonder where that puts prototype itself? I generally discourage novices from using libraries - they should first learn the language itself. For experts I usually recommend to look at libraries, take out what's good and use that. But then you still have a full range of developers for which prototype is actually a good solution but in this case will surely degrade user experience for a large part of your audience.

Patching this inconvenience is really trivial so I won't go into details about that. As for a really fast getElementsByClassName I will make a post about that soon!

Volgende: getElementsByClassName re-re-re-visited 08-'07 getElementsByClassName re-re-re-visited
Volgende: HTML5 - why not use XML syntax? 07-'07 HTML5 - why not use XML syntax?


Comments are closed