October 29, 2011

Using Javascript Timeouts for Performance

Wait, what? Doesn't setting timeouts in Javascript delay a piece of code from being run for an X amount of time, so how could it possibly help with performance?

Imagine writing a Javascript app that is doing some large, computationally-expensive task like adding a five thousand elements to the DOM:

var list = document.getElementByTagName("ul")[0];
for (var i = 0; i < 5000; i++) {
  var newElement = document.createElement("li");
  list.append(newElement);
}

Since Javascript is single threaded, executing Javascript will suspend any user interface interaction and/or updates to the page - some browsers like Chrome will even try to kill the script if it's been running for too long (have you ever seen that sad face "Oops" page?).

With the use of timers, we can split up the code into different segments (ex. 10 loops doing 500 DOM additions each):

var curr = 0; var max = 4999;
var step = 500;
var list = document.getElementByTagName("ul")[0];

setTimeout(function() {
  for (var end = curr + step; curr < end; curr++) {
    var newElement = document.createElement("li");
    list.append(newElement);
  }
  if (curr < max) { setTimeout(arguments.callee, 0); }
}, 0);

Setting the timer to 0 will tell the browser to fire off the timers as quickly as possible (in most browsers, the minimum timer delay is around 10-15ms). However, since the code is broken up into smaller pieces, it will allow the browser to do things like render updates to the page and respond to user events - basically, being more responsive (this is good!).