Handle Slow Processes Without Blocking the UI

Note: This post was inspired by work done by Nicholas Zakas. It turns out he has already written a blog article solving this problem and has a more elegant solution at Timed Array Processing in JavaScript.

Since JavaScript is executed by the same thread that handles updating the UI, developers can easily lock up the UI and make it unresponsive to end-users. Slow operations, such as bubble sorting a million value array, or adding hundreds of table rows to the DOM, will cause the JavaScript engine to lock the UI thread, making the page unusable to the end-user. To work around this, if you have large, slow operations, you can split the execution into chunks, so that the UI thread can respond to the end-user between chunks, and thereby improving the responsiveness of your site. Todays article will show you one way to chunk slow iterative operations.

How to do it…

The chunking function:
function chunkIteration(arrayToChunk, index, lengthOfChunk, operationFx) {
	var j, l = arrayToChunk.length;

	for (j = index + lengthOfChunk; index < j && index < l; index += 1) {
		operationFx(arrayToChunk[index]);
	}

	if (l > index) {
		setTimeout(function() {
			chunkIteration(arrayToChunk, index, lengthOfChunk, operationFx);
		}, 10);
	}
}

Using the chunking function:

chunkIteration(aLargeArray, 0, 100, function(o) {
	/* process the array index */
});

How it works…

The chunking function iterates through a small section of the array, 100 positions in this case, and passes the value at a given index as the first argument of a callback function. After the number of desired positions are iterated on, a short timeout is executed, letting the UI thread process any other animation or JavaScript tasks. Then the chunking function is called again continuing where it left off in processing the array.

The downside of this technique is, each timeout will drastically increase the length of time it takes to iterate through the array. However it allows your application to feel more responsive to the end-user, when iterating through a large array. I recommend using this technique when working with a large data set that doesnt immediately affect the end-user, such as processing an AJAX response or working with the Storage objects.

Theres more…

I put together a Demo Page so you can see how the UI behaves normally and when using the chunking function.