One of the essential problems with any new technology is whether to adopt it and diabolically abandon users who are not able to upgrade or miss out on new possibilities and eventually become irrelevant.
The middle way of course is to fly to the latest technologies as soon as they are stable enough but also provide fallbacks and, where necessary, reduced functionality to users of older systems. This has been the lot of any web developer for years now, where the round blue albatross around everyones necks has been IE6.
Every code path has a cost, and supporting multiple different generations of browser has a high cost (development, testing, support, maintenance, and most importantly coder misery). In recognition of this, one company has even begun passing that cost on to the customers in the shape of a markup for those who use their site with old versions of IE.
We’ve noticed that our customers are increasingly prepared to upgrade their browsers so we are preparing newer versions of some of our core libraries that jettison lots of code that only existed to upgrade older browsers as far as possible to HTML5 level capabilities. We’re also using the opportunity to allow HTML5 technologies that were necessarily bit players in the past to take center stage.
However, not all of the things we would like to do are possible yet. That’s what this post is about; places where HTML5 currently falls short that have hurt us in the last month.
Pain 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.
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 [EDIT: a commenter points out that while IE10 doesn’t run on Windows 7 at the moment, it will eventually]. What proportion of your customers are running that?
Pain 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 not currently supported by anything except Chrome.
We could use localStorage instead of the FileSytem 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.
Pain 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).
Pain 4: Details of WebWorkers patchily implemented
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.
HTML5 is a wonderful thing, filled with possibilities for letting developers soar and enabling new and interesting capabilities. But this makes it all the more frustrating when you come across inconsistently implemented features or discover that you still have to carry Internet Explorer, (in its eigth incarnation) around your neck.
It seems appropriate to end with a misquote from Marlowe’s The Tragical History of Doctor Faustus:
Thinkst thou that I who saw the face of the Web Hypertext Application Technology Working Group,
And tasted the eternal joys of the HTML5 Spec,
Am not tormented with ten thousand hells,
In being deprived of everlasting bliss?