1 Comment

Researching HTML5 Offline

I spent much of the last week prototyping and researching offline web application technologies. I am going to share some of my notes and a few useful links the team came across in the process.

A Ruby on Rails web application we developed needs its main feature to work when there is no internet available. Our only browser requirements are that the application must work on the most recent releases of Firefox (3.6+), Safari (5.0+) and Internet Explorer (8). Our goal is to stick to HTML5 standard offline technologies as much as possible.

Cache Manifest

If a web application is going to function properly without access to its web server, the browser needs to have a local cache of any resource it might need. The follow snippet from the Let’s Take This Offline chapter of the outstanding Dive Into HTML5 online book describes an offline web application well:

At its simplest, an offline web application is a list of URLs – HTML, CSS, JavaScript, images, or any other kind of resource. The home page of the offline web application points to this list, called a manifest file, which is just a text file located elsewhere on the web server. A web browser that implements HTML5 offline applications will read the list of URLs from the manifest file, download the resources, cache them locally, and automatically keep the local copies up to date as they change. When the time comes that you try to access the web application without a network connection, your web browser will automatically switch over to the local copies instead.

HTML5 lets you specify which URLs a browser needs to cache in a cache manifest file. You can specify URLs that need to be cached, URLs that should never be cached (always attempt to hit the server), and even a URL to show as a fallback when a non-cached page is requested offline. The details of the cache manifest file are discussed in great detail in the previously mentioned chapter.

All of the latest browsers support the cache manifest file with the lone exception being Internet Explorer 8. Since we need to support IE8, we looked into the recently deprecated Google Gears as an alternative. Not surprisingly Gears uses a similar manifest file to specify which resources need to be downloaded before the application can work offline. The biggest downside to using Google Gears is that the user will need to install it before they can use our application offline. Unfortunately it looks like there might not be a better choice for IE8 users.

Getting a working prototype up and running with HTML5 and/or Google Gears was pretty trivial. We used Sinatra for our prototyping. Here are some things we ran into and concerns we have going forward:

  • The cache manifest file must be served with the MIME type text/cache-manifest. Our Sinatra app serves up a static “manifest.cache” file so we added the following to our app: mime_type: cache, 'text/cache-manifest'
  • To support both HTML5 and Google Gears we will need two different versions of the manifest file. In addition, we don’t want to have to manually update a manifest file when there are new images/stylesheets/javascript files. This means dynamically generating most, if not all, of the manifest. Rack::Offline looks like it could be useful, but it appears to only support Rails3.
  • Once a browser has downloaded all of your site’s offline resources it will only update them when the manifest file changes. This is a royal pain when you are used to being able to make a change to your HTML or javascript and hit refresh to see the changes. Unless you also update something in the manifest file (like a version number) you will not see any changes. You also need to hit refresh twice. The first time the browser will detect the change to the manifest and re-download all of the resources. The second time it will display the page with the new resources. We are going to have to come up with something to make this less painful during development.
  • If you have an error in your cache manifest the browser can silently fail to use it. This leads to much developer confusion. This tutorial discusses some javascript that can be used to monitor the state of the application cache.

HTML5 Storage

In addition to needing our application’s pages be displayed when offline, we also need to be able to save changes a user makes while offline. Again from the Dive Into HTML5 book:

So what is HTML5 Storage? Simply put, it’s a way for web pages to store named key/value pairs locally, within the client web browser. Like cookies, this data persists even after you navigate away from the web site, close your browser tab, exit your browser, or what have you. Unlike cookies, this data is never transmitted to the remote web server (unless you go out of your way to send it manually). Unlike all previous attempts at providing persistent local storage, it is implemented natively in web browsers, so it is available even when third-party browser plugins are not.

All of the latest browsers, including Internet Explorer, support HTML5 Storage (also known as Local Storage). Our prototype application stored a few JSON documents and allowed the user to make changes. For example:

1
2
3
  var developer = JSON.parse(localStorage.getItem("developer") || "{}");
  developer["company"] = "Atomic Object";
  localStorage.setItem("developer", JSON.stringify(developer));

We didn’t run into any issues using HTML5 Storage on any of the browsers we tested. Our main concerns with this aspect of the offline application are:

  • How do we handle synchronizing offline changes when the user goes back online?
  • All browsers currently limit a single site to 5 megabytes of local HTML5 storage. We are going to have to make sure we stay under that limit to prevent any loss of data.