offline web applications

The network is a key component of any web application, whether it is used to download JavaScript, CSS, and HTML source files and accompanying resources (images, videos, …) or to reach web services (XMLHttpRequest and <forms>).

Yet having offline support for web applications can be very useful to users. Imagine, for example, a webmail application that allows users to read emails already in their inbox and write new messages even when they are not connected.

The mechanism used to support offline web applications can also be used to improve an application’s performance by storing data in the cache or to make data persistent between user sessions and when reloading and restoring pages.

Demo: a To Do List Manager

To see an offline web application in action, watch Vivien Nicolas’ demo (OGV, MP4), which shows a to do list manager working online and offline on an N900 running Firefox.

There are two kinds of storage global objects: sessionStorage and localStorage.

sessionStorage maintains a storage area that’s available for the duration of the page session. A page session lasts for as long as the browser is open and survives over page reloads and restores. Opening a page in a new tab or window causes a new session to be initiated.

localStorage maintains a storage area that can be used to hold data over a long period of time (e.g. over multiple pages and browser sessions). It’s not destroyed when the user closes the browser or switches off the computer.

Both localStorage and sessionStorage use the following API:

window.localStorage and window.sessionStorage {long length;// Number of items storedstring key(long index);// Name of the key at indexstring getItem(string key);// Get value of the keyvoid setItem(string key, string data);// Add a new key with value datavoid removeItem(string key);// Remove the item keyvoid clear();// Clear the storage};

Note that the storage properties are limited to an HTML5 origin (scheme + hostname + non-standard port). This means that window.localStorage from http://foo.com is a different instance of window.localStorage from http://bar.com. For example, http://google.com can’t access the storage of http://yahoo.com.

Are We Offline?

Before storing data, you may want to know if the user is online or not. This can be useful, for example, to decide whether to store a value locally (client side) or to send it to the server.

Check if the user is online with the navigator.onLine property.
In addition, you can be notified of any connectivity changes by listening to the online and offline events of the window element.

Here is a very simple piece of JavaScript code, which sends your status to a server (à la twitter).

If you set your status and you’re online, it sends the status.

If you set your status and you’re offline, it stores your status.

If you go online and have a stored status, it sends the stored status.

If you load the page, are online, and have a stored status, it sends the stored status.

function whatIsYourCurrentStatus(){var status = window.prompt("What is your current status?");if(!status)return;if(navigator.onLine){
sendToServer(status);}else{
saveStatusLocally(status);}}function sendLocalStatus(){var status = readStatus();if(status){
sendToServer(status);
window.localStorage.removeItem("status");}}
window.addEventListener("load",function(){if(navigator.onLine){
sendLocalStatus();}},true);
window.addEventListener("online",function(){
sendLocalStatus();},true);
window.addEventListener("offline",function(){
alert("You're now offline. If you update your status, it will be sent when you go back online");},true);

Offline Resources: the Cache Manifest

When offline, a user’s browser can’t reach the server to get any files that might be needed. You can’t always count on the browser’s cache to include the needed resources because the user may have cleared the cache, for example. This is why you need to define explicitly which files must be stored so that all needed files and resources are available when the user goes offline: HTML, CSS, JavaScript files, and other resources like images and video.

The manifest file is specified in the HTML and contains the explicit list of files that should be cached for offline use by the application.

the lack of ‘structured’ storage in firefox -however correct the reasoning behind not wanting to do databasestorage with sqlite- is frustrating, especially since chrome and opera are expected to provide webdb-support. is there any roadmap for inclusion of the “indexed sequential storage API” in FF?

that being said; the biggest problem for offline apps is cross-browser compatibility. i’ve been hacking on a cross-browser offline-enabled web application that can store data in a structured manner, using persistjs (a javascript library which abstracts access to localstorage, webdb, ie userdata behaviors, gears, flash, …) to store json-ified arrays/ objects, and application caching (using both html5’s and gears localserver). you can see the result, TrappistDB, here.

Isn’t there a problem with the design of localStorage? I’ve read some stuff suggesting that it’s not possible to implement the current spec in a performant way on multi-process browsers. What’s the latest on that?

One of the top thing our users wanted out of our offline app (we develop a small Product Lifecycle Management tool) is the ability to have feedback from the sync process, like “downloading 3 / 325 documents”. It was not possible at the beginning with Gears, but they eventually got it. Now, it seems that the native offline “mode” in FF cannot do the same. Or I didnd’t found the right documentation for the applicationCache javascript object… For example, I cannot access the “items” attribute described in https://developer.mozilla.org/en/nsIDOMOfflineResourceList

Started to write an ICS/iCal ‘app’ to be used in local browser mode only and also with the goal to use only HTML/CSS/JS.
This requires access to ics files stored with the local file system (also to use it with other applications like Lightning, etc).

At the moment for local storage access I’m using jQuery.twFile.js which basically uses some Moz Components.classes.
How to change that concept to use HTML5 storage so it can be used with any HTML5 platform?
Any pointer for further info / discuss?

Maybe a good article, I dont know… I got irritated after seeing a video downloading and I had no way of stopping it. And I know that I am paying for that bandwidth and helplessly watched the video loading.

Probably a HTML5 downside – we have to stop the video from downloading if we are on an expensive data plan. Now I need to get a plugin to block html5 video. In future, we are going to see ads invariably loading and eating away bandwidth, flashblock used to be so good.

To the author: cant you think from your visitor’s point of view ever, before posting that stupid HTML5 video from auto loading???? Not everyone visits your page from their unlimited home broadband.

You can open about:config in your browser, read the warning message and accept it, then right-click anywhere in the list, “New” > “Integer”
Then give the preference the name “media.preload.default” and choose 1 as the value.
Repeat with the name “media.preload.auto” and choose 2 as the value
You’re done :-)

[…] SitePointStandardists Estelle Weyl’s take on offline web appsMore fromthe folks at Mozilla on building offline web appsOpera Developers Network on building offline web apps.Critiques and gotchasas we know, all is not […]

Hi, first thks for post. Just ask you few question. I’m making some web app with offline mode and using appcache… it perfectly works with chrome browser or some mobile browser like dolphin.. but still not work for firefox. I started with firefox 3.6.26( used by my clients) and then migrate to the last one 18.0.2 but it still not work. Here are the most important file