Moving to html offline : Part 2

In part one of this short series, I mentioned some ruby on rails specific issues I encountered making an offline HTML5 app. This second short article explores some more general HTML5 offline application concepts, namely connectivity checks and cache manifest issues

– online/offline checks
When dealing with offline webapps, a major functionality of the app should be reliable detection of whether the user is online or offline. The connectivity state will impact whether the app can make any ajax requests online or if the app should store transactions in local storage (for example localStorage or websql) for synchroization later on.

In addition to this, IOS devices such as the iPad can be very tempremental. IOS has the functionality of really integrating a webapp into the IOS fabric, with features such as removing the address bar and adding an icon to the homescreen. This is fine, and really enhances the user experience (see more details on how to do this here), however in this mode the app will not be as resilient as when it is running within a browser. For example, if a webapp is offline then ANY attempt to go online will fail AND stop javascript execution (even if this is just an online check).

All this underscores the need for reliable online/offline detection. Most sites we researched pointed towards using an ajax based check to reach a particular URL. If successful, we can assume the app is online, otherwise the app is offline. If you do go down this route, note the check needs to have caching disabled. For example, if you are using jquery, you need to employ the $.ajax method, since this allows you to use the “cache: false” option.

However, as I mentioned previously this can cause a problem in some IOS based webapps since as soon as the ajax requests fails (as will be the case when the app is offline) the uncaught exception will cause the webapp to stop executing the javascript and break your app. Hence you need to make sure that you write callback functions to catch error conditions.

Another idea which is often overlooked is to use the cache manifest check as an online check. This is in fact what we ended up using as it was the most reliable. An html 5 webapp will check the cache manifest twice : once when opening the app, and again after any changes to make sure everything is loaded correctly. Using javascript events such as window.applicationCache.onerror, window.applicationCache.oncached, window.applicationCache.onnoupdate and so on, it is possible and actually easy to display different content / logic when your app is online or offline (since offline apps will throw a window.applicationCache.onerror event). A very helpful list of events can be found here:

The idea is to nest the above mentioned events within the window.onload event callback, and depending on which event is fired, perform different actions / logic. If “onerror” is fired, your app or your site is offline. If “onobsolete” is fired, you should prompt to reload the page to use the new cache manifest, and lastly, if “onnoupdate” is fired, you can assume your app and site are both online. There are more examples of what you can do with this, but that’s the basic idea to get you started

– cache manifest / webapp changes

Everytime you change the content of your html pages or javascript scripts, you need to instruct the client to download and use the new content. This can be a bit tricky since we kept on running into a lot of situations where old content kept on being loaded. Here’s a rough guide on how to handle cache manifest and webapp changes:

  • To be absolutely sure all content will be reloaded, change the name of your cache manifest file (for example from cache1.manifest to cache2.manifest). Obviously, also change the reference to you manifest file within the webapp html (example : <html manifest=”/cache2.manifest”>). This will cause your webapp to throw an “onobsolete” event and re-cache all the content
  • Another way to force a re-download of content, is to add comment line to manifest, and change this when any of your content changes
  • Sometimes, javascript content will refuse to update event with the above two tricks since the browser will cache the js files (in browser cache, not in application cache, which are two different caches). The solution is to append something like “?v=1” to javascript links within your html file (example: <script src=”/js/aomeJS.js?version=8″></script>), and also change the corresponding file names in you cache manifest. Everytime the javascript content changes, simply increment the “=1” to another number. This may seem tedious since you need to update all your <script> src links, but most web apps are single-page apps, so there should be a very small number or <script> links.

Using the above three points, we never ran into any more updating application cache issues