Multi-threaded JavaScript (sort of)
[UPDATE: It turns out that we could make a simple change on the server and remove the need for this code to run client-side. There was nothing wrong with the approach we took in the article, but decided to do it on the server as an enhancement to our API]
I just got through experimenting with web workers and pushed it out to production. Now its time to explain what I've learned.
To see historicaly videos and events, we launch a new window called the history browser. It uses SVG to create tiles, these tiles are draggable and vary in size depending on the zoom level.
When zooming out to the week view (each tile represents 24 hours of activity) We are making several requests for days and the resulting JSON can be several MBs.
We then need to coalesce those activity segments into a single video recording. This loop is where JavaScript really slows down. [Looping through 5000 records, reducing it down to ~500]
By using a seperate thread we can do the hard work without making the UI unresponsive.
worker = new Worker('../_js/workers/coalesce.js');
worker.addEventListener('message', function(e) {}, false);
worker.postMessage({ 'name': 'Mr. Orange' })
Once you've had your fun, the worker
sends a self.postMessage(msg)
back to the main thread.
In both cases, the message
listener function is passed the event object. The actual data can be reached using e.data
.
There are some restrictions on what the worker can access, the main restrictions are:
- window
- document
- the DOM
- complex objects*
Objects are strigified, then passed as strings. Be aware of this so you don't get various errors thrown. Objects are passed-by-copy instead of reference so there is a performance hit when sending data back and forth.
It is up to you as a developer to understand the perfocmance implicatons of using web workers. I wouldn't spin up a web worker everytime I need to add two numbers, so make a try them out and see where they can be deployed wisely.