I love using Web Worker API to speed up browser computation. For example, I show how to avoid a long pause while computing a large number of primes in an Angular primes example application. The speed up is very noticeable if a task can be meaningfully split into smaller chunks. At least a long computation will NOT freeze the browser's screen while the computation is running. Typically, I load separate code in web worker and start a long computation by posting a message. The result is sent back to the window using a message too.
1 | // main script |
Usually I write my own window to worker communication tools, like self-addressed to simplify the communication. Recently the author of ng-webworker Matt Slocum @mslocum showed me his very useful utility. It is a wrapper for executing an arbitrary function (without access to the lexical scope variables) in a separate web worker with an AngularJS api. I highly recommend visiting the ng-webworker demo page. The library supports 3 interesting and useful features:
1: Running an existing stand alone script with existing postMessage
and onmessage
callbacks
via promise-returning API. The main script from the example above becomes simply
1 | var worker = new Webworker('path/to/foo.js'); |
2: Running a function from the main script in a newly created web worker. The function is serialized into a blob URI and used as a source for the web worker. It is not supported by IE of course, but the rest of the browsers run just fine. I find this extremely useful. Any pure function that does not need outside variables (neither globals nor accessed via lexical scope). Finding primes is a pretty good candidate for running separately without an access to the outside scope - using just the input arguments. I prefer wrapping the web worker implementation in a factory to shield the users from these implementation details
1 | function primes(n) { |
That is it. Angular does a nice job hiding the DOM updates after promise resolution. I found that pre-initialization of web workers saves around 50ms, thus I prefer to keep at least one worker around.
3: Finally, a very nice feature of the ng-webworker API are the functions that return the
progress value during computation. AngularJS $q service supports .then
chaining with 3 callbacks,
the last being notify (progress) one. A long running computation can periodically use
the notify callback to let the window thread know its progress
1 | function primes(n) { |
Overall, I feel this is a great library with focused API and very useful features. I am looking forward to using it, as I use Web Worker more to parallelize my code.