Wednesday 14 February 2007
Chris has been working on adding offline support to Zimbra using Firefox's nascent offline capabilities. The goal is to test our APIs in the context of a large complex AJAX application, to make sure they work and are a good fit for the task He's made considerable progress and just posted a nice demo of reading email offline in Zimbra.
Ironically I think it works so well that the demo is not very exciting. You go offline, everything continues to work --- ho hum, move along, nothing to see here. Boring perhaps, but it's exactly the right user experience.
As Chris mentioned, there are four pieces to our offline puzzle:
- WHATWG client-side storage
- <link rel="offline-resource"> to put resources into the browser's offline cache
- The jar: URI scheme
- The WHATWG online/offline events and status property
Note that two of the pieces already have WHATWG specs, and the jar: URI scheme is already a de facto standard used in a variety of products. The only really new part is using <link rel="offline-resource"> to put resources in a persistent "offline cache" that won't accidentally evict your application. That is quite simple and once we're confident we have the right semantics for it, we'll definitely try to get it standardized somewhere. We're about pushing the Web forward, not just Firefox, and I hope other browsers support these APIs ASAP if they prove popular.
Putting these pieces together, Web application authors can add offline support to their applications in a very incremental way. The first thing you do is collect all static resources deployed to the Web server that you'll need offline and arrange for them to be loaded into the user's offline cache. For performance and consistency reasons, and also to minimize the number of tags required, your best bet is to roll them all into a single JAR file and make that the offline resource. (The "start page" also needs to link to itself as an offline-resource to ensure it will be available offline.) Now, when the user visits your page and signals that they want the application to be available offline, the resources will be automatically downloaded and stored. (The exact UI for this is yet to be determined; I've proposed having "bookmark the page" be that signal.) On each subsequent visit to the start page, Firefox will revalidate the cached resources and update them if they've changed on the server. This should be enough to ensure your application can at least get started while the user is offline.
Most Web apps need to talk to some server. When the browser is offline, they can't. It's up to the application developer to detect offline status using the provided APIs and decide how to behave while offline. Some functionality, such as instant messages, should just be disabled. In other cases, where the app would normally retrieve data from the server, it instead might grab some previously preloaded data. This would work well for email, calendar, CMS, and other applications. Of course the data has to be stored somewhere, and cookies won't cut it, which is where WHATWG client-side storage comes in (or another client-side storage solution, such as Flash's, if you prefer). Similarly, instead of sending data to the server, it will have to be queued and sent later when the user gets back online.
This approach to offline Web apps has some major advantages. The user isn't required to download and install anything. In fact, no trust decision is required; the application remains sandboxed exactly as if online. In fact, there's potentially no new UI required at all. The footprint requirements are small. The offline user experience is very smooth; the address in the URL bar remains the same, and the same bookmarks or shortcuts will access the application. Dynamic online/offline switching is supported. It's very incremental; there's no new tier you have to suddenly add, and no new programming model. AJAX applications tend to move logic from the server to the client and this fits right in with offline support.
Of course, this approach is also not perfect. The main issue that I see right now is that some server-based functionality, such as full-text search, may just not perform well in the browser. (However, there may be ways around that, such as uploading an index to the client, or doing the computation in a Java applet loaded from the offline cache.) I'm glad to see other approaches growing up, such as the Dojo Offline Toolkit; hopefully we'll have a range of solutions to fit all needs.
One API that we are thinking about adding is support for script-controlled loading of resources into the offline cache. This needs to be designed in conjunction with a policy for deleting resources from the offline cache, something we haven't settled on yet.
I'm really excited about seeing this taking shape. Thanks to Chris and Dave Camp, who's doing the offline cache work on the Gecko side.