javascripteventshtml5-appcachecache-manifestapplication-cache

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


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

handle appCache events and errors,

and when is swapCache needed?


Solution

  • 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.

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

    e.g.

    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.