Monday, May 19th, 2008

Some more JavaScript performance tips

Category: JavaScript, Performance

<p>Thierry Schellenbach has written up some thoughts about JavaScript optimization for Prototype apps after playing with console.profile() / console.profileEnd() in his Prototype applications.

The core advice is pretty simple:

  • Beware of $$ and event binding
  • Beware of other Prototype methods (reports a 40 times speed different between innerHTML and element.update)
  • Write to innerHTML instead of using document.createElement
  • Use for loops instead of for in loops
  • Use Array.join instead of += on a string
  • Cache variables and functions
  • Limit the usage of eval
  • Limit the usage of Try Catch statements
  • When manipulating the DOM copy the element out of DOM change it and stick it back in

We need more performance data on some of these, especially to track them over time. I have seen the opposite argued for a couple of them ;)

Related Content:

Posted by Dion Almaer at 7:09 am
12 Comments

+++--
3.3 rating from 38 votes

12 Comments »

Comments feed TrackBack URI

I would also warn about using innerHTML. Prototype’s Element#update method isn’t a straight pointer to innerHTML. It fixes a lot of cross-browser issues. Be sure you are not using innerHTML with elements like tables or some other situations because IE and Opera have problems with them.

- JDD

Comment by jdalton — May 19, 2008

Also Prototype’s new Element(‘div’) should be faster than Element.extend(document.createElement(‘div’)) because it uses cloneNode().
- JDD

Comment by jdalton — May 19, 2008

Also you can try using the “_each” method on arrays instead of the “each” to avoid the use of the try catch and setting the context.
-JDD

Comment by jdalton — May 19, 2008

Yes, innerHTML is dangerous issue (for the performance)

Comment by Snowcoredotnet — May 19, 2008

Element#update() also evaluates scripts that are injected into the document, that would otherwise be ignored by setting innerHTML.

Comment by sentientholon — May 19, 2008

Echoing Dion’s subtle hint:

http://www.sitepen.com/blog/wp-content/uploads/2008/05/stringfor.png

Specifically at the core advice “Use Array.join instead of += on a string” was directly contradicted by the data I collected during the string performance analysis I wrote about; the link above shows clearly that += beats out both using Array.join and String.prototype.concat on all major browsers.

Comment by ttrenka — May 19, 2008

@ttrenka

Array.join is a lot faster on IE6 that is why it is used. But as as IE6 share decreases, javascript developers should take note and update their code accordingly. Otherwise people will continue to do it for no reason. It’s kind of like how a lot of javascript developers still put a html comment inside of there script tags still. There is no reason to do it anymore.

Comment by howardrauscher — May 19, 2008

1) In the UIZE Framework, the Uize.Node.injectHtml static method also deals with evaluating the otherwise crippled scripts, and provides six injection modes: “inner bottom”, “inner top”, “outer bottom”, “outer top”, “inner replace”, and “outer replace”.

2) On the speed of for…in iteration for arrays, don’t use for…in for array iteration. It’s EEEEEEEEVILLLLL! Running a counter with an iterator variable is vastly more efficient. There are times when it’s worth reducing code size by a few characters, and there are times when it’s not. (see http://www.uize.com/tests/performance/array-iteration-styles.html)

3) For additional performance with the counter approach to array iteration, storing the value of the .length property in a local variable also helps (as long as the array will not be modified in length during the operation). Repeated dereferencing of the length property of the array object costs a bit.

Comment by uize — May 19, 2008

On the string concatenation point, Firefox is well optimized for building large strings using +=, while IE is most decidely not. When building large strings (like serializing JSON, XML, or building HTML for a widget), Array.join is the clear winner in IE for building large strings, while it’s mostly a wash in FF (see http://www.uize.com/tests/performance/string-concatenation-approaches.html)

Comment by uize — May 19, 2008

You can checkout this application I put together to see how different calls in JavaScript perform on different browsers.

http://www.rockstarapps.com/samples/performance/

Comment by digitalIchi — May 19, 2008

@jdalton -

In regards to cloneNode, I used to think the same thing…then I tested it. cloneNode on a cache object inside a function is slower than createElement due to the overhead of the function call & the object hash lookup. Prototype -may- be getting a bit of a speed bump by using coneNode in new Element() since the function call has already been done, but that speed gain is -very- small and is greatly trumped by the overhead of the rest of the function. In general what I’ve realized is that cloneNode on a SINGLE node is almost never worth it (as of IE7, Safari3, FF2)

Comment by cwolves — May 19, 2008

thanks for posting this and commenting, appreciate your input a lot guys.

John.

Comment by indiehead — May 21, 2008

Leave a comment

You must be logged in to post a comment.