How do you use and create a MANIFEST file (structure),
handle appCache events and errors,
and when is swapCache needed?
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.
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 anonymous-function. 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.
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.
<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);
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);
progress.
total
loaded
lengthComputable
GENERAL (for all):
clipboardData
cancelBubble
returnValue
srcElement
defaultPrevented
timeStamp
cancelable
bubbles
eventPhase
currentTarget
target
type
stopPropagation
preventDefault
initEvent
stopImmediatePropagation
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.