6. Offline Operation
HTML 5 allows us to create offline-capable websites using
a mechanism known as AppCache. The concept is very
simple. The user first opens the website in normal online mode, and it
provides the browser with a predefined text file called the
manifest file, which lists all the resources
(images, stylesheets, JavaScript, etc.) we want to be cached for offline
navigation in the future.
The next time the user visits the page, the browser will try to
download the manifest file again to see if it has changed. If it has not
changed or there is no Internet connection, the HTML document is loaded
from the cache as well as all the resources in the manifest.
Note:
Google Gears (available in Android) supports a
LocalServer API that emulates the offline manifest file with a
JavaScript API. It will be replaced over time by HTML 5 in newer
Android devices.
The architecture of our website will be exactly the same as if all
the resources had been downloaded from the server. Images, stylesheets,
and JavaScript scripts will be loaded, but they will be sourced from the
cache instead of the server.
6.1. The manifest file
The manifest is a text file, served as text/cache-manifest and defined as the
manifest attribute of the html element:
<html manifest="oursite.manifest">
The file has to start with the line CACHE MANIFEST. This line can be followed by
a series of relative or absolute URLs that we want to be cached for
offline availability. We can comment lines by using a hash at the
beginning of the line:
CACHE MANIFEST
# This is a comment
ourscript.js
images/logo.gif
images/other_image.jpg
ourstyles.css
After the initial page load the only request the browser will
send is for the manifest file, to see if it has changed. If even a
single character has changed, all the resources will be downloaded
again so the current versions are available for the next load or for a
reload action.
To ensure that the browser gets the most recent versions when
any internal changes are made to the listed resources as well as when
files are added to or removed from the list, the best and simplest way
to update the manifest file is to use a comment with the last modified
date, a version number, or a hash calculated from all the resources’
contents:
CACHE MANIFEST
# Updated 2010-08-01
The standard also defined two subgroups inside the manifest
file, but they do not work very well today on mobile browsers. The
three groups are the CACHE—the
implicit group we defined earlier—and the NETWORK and FALLBACK subgroups. In the network group we
can define a series of folders, domains, or files that will always be
fetched from the server, and in the fallback group we list a series of
prefix (folder or resource) pairs. If the browser fails to download
any resource from the server, it will use the other folder or resource
defined in the same line.
Warning:
Remember that the resources in the manifest will not be
downloaded again until we update the manifest file or invalidate the
AppCache.
These groups are defined as follows:
CACHE MANIFEST
# resources
NETWORK:
# resources
FALLBACK:
# folder_first_option folder_if_fail
CACHE:
# This list is continuing the first resource list
6.2. Cache detection
window.applicationCache is the object
JavaScript offers representing the AppCache engine. It has a status property that tells us what is
happening with the cache. The possible values are listed in Table 4.
Table 4. Status of applicationCache object
Value | Constant | Description |
---|
0 | UNCACHED | This is the first load
of the page, or no manifest file is available. |
1 | IDLE | The cache is
idle. |
2 | CHECKING | The local manifest file
is being checked against the server’s manifest
file. |
3 | DOWNLOADING | The resources are being
downloaded. |
4 | UPDATEREADY | The cache is
ready. |
Warning:
To use AppCache, we should use the HTML 5 DOCTYPE (<!DOCTYPE html>) in the HTML
file.
If the application cache status is 0 our
document is loaded from the network; otherwise, it is loaded from the
application cache.
We can manually invoke the cache update process using the
applicationCache.update() method.
However, the new resources will not be served from the cache until the
page is reloaded or we use the applicationCache.swapCache() method.
Note:
If your offline application needs to store custom images that
are only for one user (for example, pictures of the user’s
contacts), you can create a manifest file dynamically for each user
or, even better, store the images in base64 in offline storage for usage as inline images
later.
6.3. Cache events
The applicationCache object
supports many events, listed in Table 5.
Table 5. Events available for applicationCache
Event
property | Description |
---|
oncached | Executed after the
first update process finishes |
onchecking | Fired when the update
process begins |
ondownloading | Executed when the
resources begin downloading |
onerror | Fired when an error
occurs in the cache |
onnoupdate | Executed when the
update process has finished but the manifest file hasn’t
changed from the previous load |
onprogress | Fired when each
resource starts downloading |
onupdateready | Executed when the cache
is ready after a new update process was started on an existing
application cache |
Debugging AppCache issues can be problematic at the beginning.
To clear the cache in iPhone, go to Settings→Safari→Clear Cache. If you want to see what AppCache has inside, you can find a
SQLite database in the iPhone Simulator at /Library/Application Support/iPhone
Simulator/User/Library/Caches/com.apple.WebAppCache/ApplicationCache.db. More information on AppCache debugging can be found at http://www.mobilexweb.com/go/appcache. |
Table 6 reports
on browser compatibility with AppCache.
Table 6. AppCache compatibility table
Browser/platform | AppCache
support |
---|
Safari | Yes |
Android
browser | Yes, from 2.0 (Gears
before 2.0) |
Symbian/S60 | No |
Nokia Series
40 | No |
webOS | Yes |
BlackBerry | No |
NetFront | No |
Internet
Explorer | No |
Motorola Internet
Browser | No |
Opera
Mobile | No |
Opera
Mini | No |
Note:
Web Workers is a possible HTML 5 feature that allows
JavaScript to execute different threads at the same time. At the
time of this writing, no mobile browser implements it.