SpiderOak/crypton — pull request #178 by ecto (2014-02-12 23:37:51+00:00)
Title: Web workers

Authentication was blocking the UI for up to 10 seconds on an iPhone 4, and was hindering my work. Because all of our crypto libs are synchronous, the only solution I could come up with to mitigate freezing was to use web workers. This is just one way to implement this, and it could be the wrong way.

Web Workers don't work on Android < 4.4 and we don't want to cut support for a bunch of devices, so if we're going to use web workers we'll have to make them optional. The DRYest way I could find was to optionally proxy an object to a worker if the browser supports them. This way, all the calls from the library are the same and we transparently upgrade to working in the background if we can. I've abstracted the expensive parts of authentication, SRP calculations and the decryption of the account columns, to a `crypton.work` object.

There are caveats inherent in this design: every function in `crypton.work` must be stateless, have a callback, and all data passed around with callbacks must be a JS primitive. I've refactored the `unravel()` function to work around this by reconstructing the Key objects in the main thread (cheap) and doing the decryption in the work function (expensive).

After testing, the UI doesn't lock up during authentication on my iPhone anymore and a few seconds have been shaved off the whole process. There are still a lot of expensive parts that we can abstract, but I figured this would be a good starting point.