1 – Internet Explorer
The party over the passing of IE6 (and in our case IE7 too) is barely over before you start realising that better though it is, IE8 is still not in any sense a ‘modern browser’ (that wonderful euphemism for ‘browser not built by Microsoft’). In fact, we are going to make extensive use of WebSockets and WebWorkers and they aren’t even in IE9.
There goes another code path and we still haven’t moved beyond the old rule: one way for IE and one way for everything else.
IE8 doesn’t even have ecmascript5, so you’ll have to decide what to do about array.indexOf, array.each, Date.now() (creates less garbage than +(new Date)), getter and setter properties and a host of other, useful javascript upgrades. Of course you’ll be working without strict mode too.
Oh yes, in IE8 and IE9, you can do cross origin requests, but not using an XMLHttpRequest, while in IE10 XMLHttpRequest is updated to support the new functionality. This means that you can’t use the fact that XDomainRequest is there to indicate you should use it, as you probably want to start using the normal API in IE10.
Only IE10 is really comparable with ‘modern browsers’ and that won’t even run on anything older than Windows 8 a commenter points out that while IE10 doesn’t run on Windows 7 at the moment, it will eventually. What are running that?
2 – Variety of offline storage options, all insecure
When there’s a problem, we need to be able to investigate it by getting logs. For many web pages, nothing much interesting is happening on the client so logs from the server are fine, but for our application, which might run for days without a page reload we need more insight into what is happening on the client.
The problem is that logging slows the client down and results in memory growth, so we can only enable it after we know there is a problem, which is often too late. Using pre-html5 technologies, the best we could do was store a predefined number of the last log messages in a lazy format to keep the performance hit low and ask the user to retrieve them when there was a problem.
The dream of course, is that logs are written in the background (so as not to reduce the responsiveness of the client) to some form of offline storage, and can be retrieved after something has gone wrong, even if the machine has been rebooted in between.
This could be achieved by writing to the FileSystem API in a WebWorker except that the FileSystem API is browser support for FSAPI not currently supported by anything except Chrome.
We could use localStorage instead of the FileSystem API, except that localStorage is a synchronous API so a lot of data there would increase load times.
Even worse, we can’t actually store logs unencrypted on the local machine because they might have sensitive information in them. Suddenly our simple logging solution is looking quite messy, unperformant and requires us implementing our own encryption, since there is no encryption API for storage (or in fact anything) in HTML5. I think it’d make a good addition to the standard library.
3 – No good support for sharing between windows
Sometimes, you’d like to be able to share connections to the same server across many different windows. This is particularly good if you’ve got elements that the user can pop-out, but if a user opens two different tabs to the same application it’d be nice for them to share the connection too. We’ve got access to postMessage now, which greatly improves the code, but only if you have a handle to the window you want to send messages to. How can you discover other tabs that may have been opened by the user? In Chrome, they are not even running in the same process. This kind of functionality will be necessary to create long running applications that behave like services.
You could use a SharedWebWorker instead for this except that it isn’t supported by Firefox.
You could use an onstorage event to broadcast to all the other windows, except that not all browsers give you the handle to the window doing the storing on that event (it’s not part of the spec).
4 – Details of WebWorkers patchily implemented
We’re very keen to use webworkers where possible to receive and parse our data, since receiving multiple thousands messages a second can start to impact responsiveness if you’re doing it on the main javascript thread.
Unfortunately Firefox doesn’t support WebSockets inside Workers (there’s an under appreciated bug report).
Neither Chrome nor Firefox correctly resolve Worker scripts based on the location of the code that instantiates them rather than the page itself, so our library must be deployed on the same webserver as the page is served from (no CDN for you!), and it can’t be included by pages at different levels in the hierarchy, nor can the script file be renamed without a code change. This despite the fact that the spec is clear that worker scripts should be resolved relative to the instantiating script.