Thursday, February 5th, 2009

Speeding up your JavaScript: Part 3 and 4

Category: JavaScript, Performance

Nicholas C. Zakas wraps up his series on speeding up JavaScript with two more posts on the subject.

First up, he delves deeper into a generic memoizer:

In part 2 of this series, I wrote briefly about handling too much recursion in a function through memoization. Memoization is a technique for caching previously calculated values so that they need not be recalculated; when a recursive function is doing such a calculation, memoization is incredibly useful. The memoizer I presented was Crockford’s, and is useful primarily for recursive functions that return integers. All recursive functions, of course, don’t return integers. A more generic memoizer() function can be created to deal with any type of recursive function:

< view plain text >
  1. function memoizer(fundamental, cache){
  2.     cache = cache || {}
  3.     var shell = function(arg){
  4.         if (!(arg in cache)){
  5.             cache[arg] = fundamental(shell, arg)
  6.         }
  7.         return cache[arg];
  8.     };
  9.     return shell;
  10. }

Then he gets into other examples, and concludes:

The bottom line: always be on the look out for recursion in your JavaScript. Memoization and iteration are two ways to avoid excessive recursion and the long-running script dialog.

The final part of the series deals with the DOM, and looks at practices such as using DOMFragments instead of touching the live DOM (John Resig has been talking a lot about that):

< view plain text >
  1. var fragment = document.createDocumentFragment();
  2. for (var i=0; i < items.length; i++){
  3.     var item = document.createElement("li");
  4.     item.appendChild(document.createTextNode("Option " + i);
  5.     fragment.appendChild(item);
  6. }
  7. list.appendChild(fragment);

Posted by Dion Almaer at 5:15 am

4.1 rating from 18 votes


Comments feed TrackBack URI

The “in” check unfortunately is not that reliable … as you said this is perfect for fibonacci stuff but with object or different results there are a couple of problems …
var o = {"a":true};
var a = {toString:function(){return "a"}};
alert(a in o);

In my opinione the best cache scenario is a stack with usage of Array.prototype.indexOf but latter method is still not present in every IE and for this reason it slows down stack based cache object (it always depends how many results we expect in every case)

btw, performances uh? so use ternary ;-) – and I think the shell as argument is not necessary as well …
function memoizer(fundamental, cache){
cache = cache || {};
return function(arg){
return arg in cache ?
cache[arg] :
(cache[arg] = fundamental(arg))

Comment by WebReflection — February 5, 2009

ehr … ok, I guess the shell arguments is necessary, sorry :D

Comment by WebReflection — February 5, 2009

Could we also assign innerHTML strings to a DocumentFragment? If so, do we still get a better preformance?

Comment by jaysmith — February 6, 2009

Leave a comment

You must be logged in to post a comment.