Since I work quite a bit with HTML5 I decided to write about it whenever I discover a feature that I think is quite neat. So this blog post is about “Offline Web Applications”. This is based on the functionality described here: http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html. If you take a look at it you’ll find that this is rather cryptic and dry. So here is a short step by step description on how this works.
The idea behind offline web apps is that much of the functionality of a web app could/should be available even when not being connected to server. Take a stand alone game as an example. There is no need for a standing connection to the server. Another good example is a web based email client. When you are connected to the web site you can send and receive email. However, once loose connectivity why should you not be able to read previously downloaded emails or draft new ones? These are the usage models that this specification tries to enable.
But enough talk, let’s jump right into it. For this example I’m using Aptana 3 as IDE and Firefox as browser; others will work as well. Let’s start with a very simple page.
<!DOCTYPE html> <html> <body> Hello World. </body> </html>
To indicate that you want the browser to cache your web application you refer to a manifest file. The manifest lists all resources that you want the browser to download and cache. Those resources can be html, js, css, images and many others. Adding manifest="example.manifest” to the <html> tag will do the trick. You can call the manifest as you want. I called mine example.manifest. So here is the modified version:
<!DOCTYPE html> <html manifest="example.manifest”> <body> Hello World. </body> </html>
The manifest is text file and has to start with “CACHE MANIFEST”. It allows for a quite complex control about what is cached and what not. In the simplest case you just specify all resources you want to have cached, one resource per line. So our manifest looks as follows:
CACHE MANIFEST index.html
Before we start running this example, let’s get familiar with Firefox. If you open Firefox and type “about:cache” into the address bar you come to a page that looks similar to the screenshot below. There is an entry for “Offline cache device”. This is the place where your application will show up, once it is cached. For now you see a 0 for the number of entries, so nothing is cached.
Let’s run our example. If you use Aptana it will set up a small local webserver, start an instance of Firefox and point to your page. If you use a different environment you might have to do those things manually. If done correctly you should see the same as in the screenshot below.
The first time you run a web application that wants to be cached Firefox will ask you for permission. So grant it for now. Let’s check if it was actually cached. If you reload the “about:cache” tab you’ll see that now 2 items are cached. It even provides a link where you can see which files have been cached.
To have even more control about offline caching and to revoke granted permissions you can check in Firefox the Network Panel (Options->Advanced->Network). In the screenshot below you see that I granted permissions to localhost and it stored a total of 119 bytes in the cache.
So that would complete this simple blog post about offline web apps. However there is one more important thing that I want to demonstrate. For this let’s change our simple example and replace “Hello World” with “Hello Buddy”. Save it and reload the page in your browser. So what do you see? Is it what you expect? Why didn’t it update the page?
For this it is important to understand how the browser handles cached content. The whole idea behind caching is to not download the cached content again. So when you press reload, the browser simply uses the cached content and you see the old “Hello World”. The only item that the browser checks, is the manifest. If there is a modified manifest, the browser downloads it, then downloads all the resources mentioned by the manifest, and only then replaces the content of the cache. Most developers address this by adding a version number as a comment to the manifest. A comment line in the manifest starts with a #. Anything following that is a comment. For our example let’s add “# version 1” as a second line to the manifest. Save it and reload the page. The page still shows the old string because the browser used the old cache for displaying before checking for an update. Reload once more and now the text changed. That’s because the browser did replace the old cache with a new version after the last reload.
So this concludes this blog post. Let me know something is not clear, or if you have problems reproducing the example.