Gmail for mobile HTML5 Series - Part 2: Using AppCache to Launch Offline
On April 7th, Google launched a new version of Gmail for mobile for iPhone
and Android-powered devices built on HTML5. We shared the behind-the-scenes story through
this
blog and decided to share more of our learnings in a brief series of follow up blog
posts.
Last week we explained how to go about creating a simple
manifest file, and how the browser uses it to load a page. This week we will go a bit more
in-depth about the subject.
One of the problems we faced in creating our
manifest file, was how to update it when our javascript changes. At first we thought that we
might have to change one of the URLs each time we wanted to push an update. As it turns out,
the URLs listed in the manifest do not have to change at all in order cause an update,
changing the whitespace or a comment will also do the trick. For Gmail, we a comment in the
manifest that contains a hash of all of the resources listed in the manifest. That way, if any
of the resources change, the manifest will also change and cause a background update to occur
for all of our clients. An example of what this looks like is shown below.
CACHE MANIFEST
# version: 3f1b9s84
jsfile1.js
... other URLs ...
There are
other types of entries that are possible in a manifest, but that the iPhone does not currently
support. According to the spec, there are 3 categories of URLs that can be listed in a
manifest:
- Cache (what we have dealt with so
far),
- Fallback,
- Network
Although
fallback and network URLs are not yet supported on the iPhone, they are mostly supported in
the
Webkit
Nightly builds. Network URLs are those that are never cached by AppCache, and that
are allowed to be satisfied by the network. Fallback URLs are those that are attempted, and
then satisfied by by AppCache only if the network attempt fails. Both Network and Fallback
URLs are prefix matches. An example of what this looks like is shown below.
CACHE MANIFEST
jsfile1.js
NETWORK:
/images/
FALLBACK:
/thumbnails/
images/missing_thumb.jpg
This manifest tells
the browser that GET requests to any URL under /images/ are allowed to hit the server. Without
this being listed, GET requests for it would fail immediately. This manifest also tells the
browser that URLs under /thumbnails/ are allowed to hit the server, but if they fail, satisfy
the request by server
missing_thumb.jpg, which will be stored in AppCache.
So far all of the features we've covered about AppCache have not needed any Javascript to
use them. This is undoubtedly by design, as it makes it extremely easy to use. However, it is
always useful to know what advanced functionality can be unlocked using Javascript. The
Application Cache is exposed as a singleton through
window.applicationCache. It provides events that can be used to indicate
when updates are happening and a
status property that can be one of:
- 0 -
UNCACHED
- 1 - IDLE
- 2 - CHECKING
- 3 -
DOWNLOADING
- 4 - UPDATEREADY
In Gmail, we use the
status property to determine if the
page was loaded out of AppCache, or if it was loaded from the network. In order to do this, we
have the following code run at the
very start of page load:
if (window.applicationCache.status == 0) {
// Page was loaded from the Network.
} else {
// Page was loaded from
AppCache
}
There are also a couple
of functions available,
swapCache
and
updateCache, which we'll not go
into detail on since we have not found any use for them yet.
Stay tuned
for the next post where we will explore how to use the sqlite3 command-line tool to inspect
the iPhone Simulator's AppCache database. And just another reminder that we'll be at
Google
I/O, May 27-28 in San Francisco presenting a
session on how we use HTML5. We'll also be available at the
Developer
Sandbox, looking forward to meeting you in person.
ReferencesThe HTML5 working
draft:
http://dev.w3.org/html5/spec/Overview.htmlWHATWG working draft:
http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html#appcacheApple's MobileSafari documentation:
http://developer.apple.com/webapps/docs/documentation/AppleApplications/Reference/SafariJSRef/DOMApplicationCache/DOMApplicationCache.htmlWebkit Source Code:
http://trac.webkit.org/browser/trunk/WebCore/loader/appcacheBy Andrew
Grieve, Software Engineer, Google Mobile