How to use/create a MANIFEST, handle appCache events/errors and the use of swapCache

Aleksander Azizi picture Aleksander Azizi · Nov 18, 2013 · Viewed 11k times · Source

How do you use and create a MANIFEST file (structure),

handle appCache events and errors,

and when is swapCache needed?

Answer

Aleksander Azizi picture Aleksander Azizi · Nov 18, 2013

Use Application Cache With Manifest

To use application cache you need to reference to the manifest file inside the HTML document, like this:

<html manifest="manifest.appcache"/>

The manifest file itself needs a predetermined layout to work.

CACHE MANIFEST is mandatory, and needs to be at the top (so that when the browser checks if it is a cache manifest, it returns true).

CACHE is optional, but recommended, and used for referring to the files you want cached locally.

FALLBACK is optional, and is used to specify file(s) that should be used if the specified one (in CAHCE) is unavailable. The first file specified (in FALLBACK) is the original file, and the second file is the one that will be used if the original file is unavailable.

NETWORK should be considered to be mandatory, but isn't. It is used to specify what files needs an internet connection (isn't cached). Using "*" (without the brackets) specifies that all other files except the ones mentioned in CACHE, needs an active internet connection.

Example:

CACHE MANIFEST

CACHE:
YourFirstFile.html
YourSecondFile.png
fallbackFile1.html
fallbackFile2.png
Etc.css

FALLBACK:
YourFirstFile.html fallbackFile1.html
YourSecondFile.png fallbackFile2.png

NETWORK:
*

The manifest (and its specified resources) is only checked upon page load (when the user enters the site). Side note: The manifest file is case sensitive.


Handling events triggered in application cache

The first thing I want to say is appCache is really window.applicationCache, so it needs to be declared (var appCache = window.applicationCache;).

When a user enters the site for the first time (or the manifest cache isn’t present), the following events are triggered; if everything works as it should:

Creating Application Cache with manifest

Application Cache Checking

Application Cache Downloading

Application Cache Progress (0 of X)

Application Cache Cached

Let’s break it down.

The first (Creating Application Cache) specifies a cache “file/folder” for the browser to use later on.

The second (Application Cache Checking) "checking", looks inside the manifest file to see what it needs to cache.

The third (Application Cache Downloading) "downloading", begins the download process of the files specified in the manifest.

The fourth (Application Cache Progress) "progress", keeps track of the downloading progress (this is triggered for each file).

The fifth (Application Cache Cached) "cached", simply says “i’m done” caching the files, and everything went as it should.

What does this mean? It means that we can have some control over the events, and can trigger our own events if we’d like to.

So by listening to the progress event, we can display a progress bar, a notification with steps or really whatever we want.

appCache.addEventListener("progress", function(event) {
    console.log(event.loaded + " of " + event.total);
}, false);

Wait, what did I just do?

I added an event listener with an . Within this function I pass on an “event” from what we are listening to (downloading), and simply logged how many files has been cached thus far and how many files there are in total.

Let's do this on all the events mentioned, from the first called event, to the last:

appCache.addEventListener("checking", function(event) {
    console.log("Checking for updates.");
}, false);


appCache.addEventListener("downloading", function(event) {
    console.log("Started Download.");
}, false);


appCache.addEventListener("progress", function(event) {
    console.log(event.loaded + " of " + event.total + " downloaded.");
}, false);

appCache.addEventListener("cached", function(event) {
    console.log("Done.");
}, false);

Now these events do what I want them to.

These are the appCache events:

checking - Always the first event triggered. Checks for an update in the manifest.

downloading - Triggered when an update is found. Downloads resources specified in the manifest.

progress - Triggered for each resource currently downloading. Tracks the progress (by file).

error - Triggered if 404, 410 network error occurs, or the manifest file was changed while downloading.

obsolete - Triggered if 404, 410 network error occurs, or the manifest file doesn't exist (on the server). Note that this event will delete previous (and current) application cache.

cached - (Only) Triggered the first time the resources specified in the manifest is cached.

noupdate - Triggered if no change has been made to the manifest since the last cache update.

updateready - Triggered if new resources are downloaded.


Scenario handling (error(s), events and triggers)

What if something goes wrong? We can handle that with error and/or obsolete.

error is triggered when something goes wrong while updating.

e.g.

  • A file specified in the manifest does not exist on the server.
  • The manifest is changed while downloading.

obsolete is triggered when the manifest file doesn't exist (on the server).

e.g.

  • The manifest file is deleted from the server.
  • The website points to an invalid url/path (<html manifest="manifest.appcache"/>).

By listening to error, we can, for example, tell the user if something goes wrong:

appCache.addEventListener("error", function(event) {
    if (navigator.onLine == true) { //If the user is connected to the internet.
        alert("Error - Please contact the website administrator if this problem consists.");
    } else {
        alert("You aren't connected to the internet. Some things might not be available.");
    }
}, false);

Here I checked if the user have an active internet connection or not. Keep in mind that this is just an example, telling the user might not be necessary (depending on your website).

We can do the same thing with obsolete, but we might not want to tell the user about it, as this is a server side problem:

appCache.addEventListener("obsolete", function(event) {
    console.log("Obsolete - no resources are cached, and previous cache(s) are now deleted.");
}, false);

swapCache

Now this is a tricky one. The main questions about swapCache is; "What does it do?", "Is it useful/needed?" and "Should it be used?".

swapCache is used to replace the old cache with the new one. It can only be used inside the updateready event (if used elsewhere, it will throwback an error).

"What does it do?": swapCache does what it says, swaps the current cache with a new one.

"Is it useful/needed?": appCache is useful, the main reason to use it would be to make sure the newsiest cache available is used. Altho this seems like a thing that should work by itself, that's not always the case. For example, some browsers don't always use the latest cache as haven't gotten the message that it needs to (the iPhone is a good example ). An image might be cached, then deleted/renamed, then cached, and so on. In the end, the browser might use an old cache to display that image because of the reference it already has with the stored caches(s). Bottom line: Is it useful? yes. Is it needed? no.

"Should it be used?": Personally I would say yes. But it depends on what your page does. If the criteria from the example above matches your resource handling, then yes. Otherwise it wouldn't really matter.

so by adding an event listener to updateready, we can include swapCache:

appCache.addEventListener("updateready", function(event) {
    appCache.swapCache();
    window.reload();
}, false);

(appCache) Event variables:

progress.
         total 
         loaded 
         lengthComputable
GENERAL (for all):
         clipboardData
         cancelBubble
         returnValue
         srcElement
         defaultPrevented
         timeStamp
         cancelable
         bubbles
         eventPhase
         currentTarget
         target
         type
         stopPropagation
         preventDefault
         initEvent
         stopImmediatePropagation

Nice external pages:

http://www.html5rocks.com/en/tutorials/appcache/beginner/ - appCache basics.

http://www.htmlgoodies.com/html5/other/html-5-appcache-by-example.html - appCache example.

http://www.jefclaes.be/2012/04/visualizing-offline-application-cache.html - manifest FALLBACK.

Is swapCache() required in HTML5 offline apps? - swapCache information (read the comments as well).

https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching - general HTTP cache information.