Friday, October 26th, 2007

Running CPU Intensive JavaScript Computations in a Web Browser

Category: Gears, JavaScript

Julien Lecomte has written up the pattern where you use setTimeout() to keep yielding control back to the main thread so that it can handle browser events.

Completion Callback

javascript

  1. function doSomething (callbackFn [, additional arguments]) {
  2.     // Initialize a few things here...
  3.     (function () {
  4.         // Do a little bit of work here...
  5.         if (termination condition) {
  6.             // We are done
  7.             callbackFn();
  8.         } else {
  9.             // Process next chunk
  10.             setTimeout(arguments.callee, 0);
  11.         }
  12.     })();
  13. }

Progress Callback

javascript

  1. function doSomething (progressFn [, additional arguments]) {
  2.     // Initialize a few things here...
  3.     (function () {
  4.         // Do a little bit of work here...
  5.         if (continuation condition) {
  6.             // Inform the application of the progress
  7.             progressFn(value, total);
  8.             // Process next chunk
  9.             setTimeout(arguments.callee, 0);
  10.         }
  11.     })();
  12. }

Of course, the Gears Workerpool does this the right way, giving you the ability to pass messages to another process to get the work done in a secure sandbox.

As a band-aid it could be nice to have an abstraction library that uses WorkerPool if Gears is installed, if not, try to use setTimeout (which is harder to do as you need to cut up the work differently).

Posted by Dion Almaer at 7:21 am
9 Comments

++++-
4.3 rating from 71 votes

9 Comments »

Comments feed TrackBack URI

This method is being used for over ten years now. Have a look at something way more advanced: continutations.

http://marijn.haverbeke.nl/cps/

Comment by Robbert Broersma — October 26, 2007

@Robbert,

This isn’t a new pattern, of course. My goal in this article was to present this well known pattern under a new light, and discuss ways of reducing the overhead associated with it without sacrificing user interface reactivity.

Regards

Comment by Julien Lecomte — October 26, 2007

…now why didn’t I think of that? I’m always locking my browser down with JavaScript — I usually just depend on nice, muted, pastel-coloured “waiting” screen to pacify users…

Comment by mdmadph — October 26, 2007

This and the continuation approach are neat ideas, but I would also argue that if your code is encountering very heavy blocks (number crunching, large DOM node creation or ?) often, your approach could probably be refactored a little bit or perhaps moved to the backend if appropriate. I say this only because of JS’ current non-threaded, blocking-type behaviour (“this is what we have to work with”, etc.)

Comment by Scott Schiller — October 26, 2007

@Scott

I totally agree with you, and point this out in the last paragraph of the original article.

Comment by Julien Lecomte — October 26, 2007

Well, the browser *can* handle CPU intensive computations to some extent (see the examples linked in the original article) and hopefully, with the next generation JavaScript engines (Tamarin), this will be even more true. The real question is whether doing that computation on the client is the *best* approach, and this depends on your situation.

Comment by Julien Lecomte — October 26, 2007

An old technique to solve a still current problem, so it is good to revisit it, especially where resources are a consideration. This is making me think about mobile browsing applications: A JS computation can be CPU intensive because it’s running on a 400MHz ARM rather than a 3Ghz P4 — heavy code blocks are relative to the platform.
I am inspired to do some mobile browser tests, as it’s often very hard to determine if a device is hanging or I’m not pressing the screen right!

Comment by Charles — October 26, 2007

@Julien – Good point, the examples definitely show a way to overcome that hurdle.

Comment by Brad Harris — October 26, 2007

This trouble is focused in the GWT’s IncrementalCommand interface. I’m developing a text compressor with this pseudo concurrent approach.

Comment by Andrés Testi — October 26, 2007

Leave a comment

You must be logged in to post a comment.