Erste Schritte zur Verwendung des Anwendungscaches

Einleitung

Es wird immer wichtiger, dass webbasierte Anwendungen offline zugänglich sind. Ja, alle Browser können Seiten und Ressourcen über längere Zeit im Cache speichern, wenn sie dazu aufgefordert werden. Der Browser kann jedoch jederzeit einzelne Elemente aus dem Cache entfernen, um Platz für andere Dinge zu schaffen. Bei HTML5 werden über die ApplicationCache-Schnittstelle einige der Ärgernisse der Offline-Nutzung beseitigt. Die Verwendung der Cache-Schnittstelle bietet Ihrer Anwendung drei Vorteile:

  1. Offline-Surfen: Nutzer können Ihre gesamte Website aufrufen, wenn sie offline sind.
  2. Geschwindigkeit: Ressourcen kommen direkt von der Festplatte, ohne dass dafür eine Netzwerkverbindung hergestellt werden muss.
  3. Robustheit: Wenn Ihre Website wegen Wartungsarbeiten nicht verfügbar ist, z. B. weil jemand versehentlich alles kaputt macht, können Ihre Nutzer offline arbeiten.

Mit dem Application Cache (oder AppCache) kann ein Entwickler angeben, welche Dateien der Browser im Cache speichern und für Offline-Nutzer verfügbar machen soll. Ihre App wird korrekt geladen und funktioniert korrekt, auch wenn der Nutzer offline auf die Aktualisierungsschaltfläche drückt.

Cache-Manifestdatei

Die Cache-Manifestdatei ist eine einfache Textdatei mit den Ressourcen, die der Browser für den Offline-Zugriff im Cache speichern soll.

Verweis auf eine Manifestdatei

Um den Anwendungscache für eine App zu aktivieren, fügen Sie das Manifestattribut in das html-Tag des Dokuments ein:

<html manifest="example.appcache">
  ...
</html>

Das Attribut manifest sollte auf jeder Seite Ihrer Webanwendung enthalten sein, die im Cache gespeichert werden soll. Eine Seite, die das Attribut manifest nicht enthält, wird vom Browser nicht im Cache gespeichert, es sei denn, sie ist in der Manifestdatei selbst explizit aufgeführt. Das bedeutet, dass jede Seite, die der Nutzer mit einem manifest aufruft, dem Anwendungscache hinzugefügt wird. Daher muss nicht jede Seite in Ihrem Manifest aufgelistet werden. Wenn eine Seite auf ein Manifest verweist, kann nicht verhindert werden, dass diese Seite im Cache gespeichert wird.

Die vom Anwendungscache gesteuerten URLs finden Sie in Chrome unter „about://appcache-internals/“. Von hier aus können Sie Caches leeren und die Einträge ansehen. In Firefox gibt es ähnliche Entwicklertools.

Das Attribut manifest kann auf eine absolute URL oder einen relativen Pfad verweisen. Eine absolute URL muss sich jedoch am selben Ursprung wie die Webanwendung befinden. Eine Manifestdatei kann eine beliebige Dateiendung haben, muss aber mit dem richtigen MIME-Typ bereitgestellt werden (siehe unten).

<html manifest="http://www.example.com/example.mf">
  ...
</html>

Eine Manifestdatei muss mit dem MIME-Typ text/cache-manifest bereitgestellt werden. Möglicherweise müssen Sie Ihrem Webserver oder der .htaccess-Konfiguration einen benutzerdefinierten Dateityp hinzufügen.

Um beispielsweise diesen MIME-Typ in Apache bereitzustellen, fügen Sie diese Zeile in Ihre Konfigurationsdatei ein:

AddType text/cache-manifest .appcache

Oder fügen Sie in Ihre app.yaml-Datei in Google App Engine Folgendes ein:

- url: /mystaticdir/(.*\.appcache)
  static_files: mystaticdir/\1
  mime_type: text/cache-manifest
  upload: mystaticdir/(.*\.appcache)

Diese Anforderung wurde vor einiger Zeit aus der Spezifikation entfernt und ist für die aktuellen Versionen von Chrome, Safari und Firefox nicht mehr erforderlich. Sie benötigen jedoch den MIME-Typ, um in älteren Browsern und IE11 zu funktionieren.

Struktur einer Manifestdatei

Das Manifest ist eine separate Datei, die Sie über das Manifest-Attribut im HTML-Element verlinken. Ein einfaches Manifest sieht in etwa so aus:

CACHE MANIFEST
index.html
stylesheet.css
images/logo.png
scripts/main.js
http://cdn.example.com/scripts/main.js

In diesem Beispiel werden auf der Seite, auf der diese Manifestdatei angegeben ist, vier Dateien im Cache gespeichert.

Beachten Sie dabei Folgendes:

  • Der String CACHE MANIFEST ist die erste Zeile und obligatorisch.
  • Dateien können aus einer anderen Domain stammen
  • Einige Browser schränken die Größe des Speicherkontingents ein, das Ihrer Anwendung zur Verfügung steht. In Chrome verwendet AppCache beispielsweise einen gemeinsamen Pool TEMPORARY Speicher, den andere Offline-APIs freigeben können. Wenn Sie eine App für den Chrome Web Store schreiben, kann diese Einschränkung mithilfe des unlimitedStorage aufgehoben werden.
  • Gibt das Manifest selbst einen 404- oder 410-Fehler zurück, wird der Cache gelöscht.
  • Wenn das Manifest oder eine darin angegebene Ressource nicht heruntergeladen werden kann, schlägt die gesamte Cache-Aktualisierung fehl. Bei einem Fehler verwendet der Browser weiterhin den alten Anwendungscache.

Sehen wir uns ein komplexeres Beispiel an:

CACHE MANIFEST
# 2010-06-18:v2

# Explicitly cached 'master entries'.
CACHE:
/favicon.ico
index.html
stylesheet.css
images/logo.png
scripts/main.js

# Resources that require the user to be online.
NETWORK:
*

# static.html will be served if main.py is inaccessible
# offline.jpg will be served in place of all images in images/large/
# offline.html will be served in place of all other .html files
FALLBACK:
/main.py /static.html
images/large/ images/offline.jpg

Zeilen, die mit einem Rautezeichen (#) beginnen, sind Kommentarzeilen. Sie können jedoch auch einem anderen Zweck dienen. Der Cache einer Anwendung wird nur aktualisiert, wenn sich die zugehörige Manifestdatei ändert. Wenn Sie also beispielsweise eine Bildressource bearbeiten oder eine JavaScript-Funktion ändern, werden diese Änderungen nicht noch einmal im Cache gespeichert. Sie müssen die Manifestdatei selbst ändern, um den Browser zu informieren, dass im Cache gespeicherte Dateien aktualisiert werden sollen.

Vermeiden Sie die Verwendung eines kontinuierlich aktualisierten Zeitstempels oder eines zufälligen Strings, um Aktualisierungen jedes Mal zu erzwingen. Das Manifest wird während eines Updates zweimal geprüft, einmal zu Beginn und einmal, nachdem alle im Cache gespeicherten Dateien aktualisiert wurden. Wenn sich das Manifest während der Aktualisierung geändert hat, hat der Browser möglicherweise einige Dateien von einer Version und andere Dateien von einer anderen Version abgerufen, sodass der Cache nicht angewendet wird und der Browser den Vorgang später wiederholt.

Obwohl der Cache aktualisiert wird, verwendet der Browser diese Dateien erst, wenn die Seite aktualisiert wurde, da Aktualisierungen erst nach dem Laden der Seite aus der aktuellen Version des Caches erfolgen.

Ein Manifest kann drei verschiedene Abschnitte enthalten: CACHE, NETWORK und FALLBACK.

CACHE:
Dies ist der Standardabschnitt für Einträge. Dateien, die unter diesem Header (oder direkt nach CACHE MANIFEST) aufgeführt sind, werden nach dem ersten Download explizit im Cache gespeichert. NETWORK:
Die in diesem Abschnitt aufgeführten Dateien stammen möglicherweise aus dem Netzwerk, wenn sie nicht im Cache gespeichert sind. Andernfalls wird das Netzwerk nicht verwendet, selbst wenn der Nutzer online ist. Sie können hier bestimmte URLs auf die weiße Liste setzen oder einfach auf "" setzen, wodurch alle URLs zugelassen werden. Für die meisten Websites ist "" erforderlich. FALLBACK:
Ein optionaler Bereich, in dem Fallback-Seiten angegeben werden, wenn eine Ressource nicht zugänglich ist. Der erste URI ist die Ressource, der zweite das Fallback, das verwendet wird, wenn die Netzwerkanfrage fehlschlägt oder Fehler auftritt. Beide URIs müssen aus demselben Ursprung wie die Manifestdatei stammen. Sie können sowohl bestimmte URLs als auch URL-Präfixe erfassen. „images/large/“ erfasst Fehler von URLs wie „images/large/whatever/img.jpg“.

Das folgende Manifest definiert eine Catch-all-Seite (offline.html), die angezeigt wird, wenn der Nutzer versucht, offline auf das Stammverzeichnis der Website zuzugreifen. Außerdem wird darin deklariert, dass für alle anderen Ressourcen (z.B. Ressourcen, die sich auf einer Remote-Website befinden) eine Internetverbindung erforderlich ist.

CACHE MANIFEST
# 2010-06-18:v3

# Explicitly cached entries
index.html
css/style.css

# offline.html will be displayed if the user is offline
FALLBACK:
/ /offline.html

# All other resources (e.g. sites) require the user to be online.
NETWORK:
*

# Additional resources to cache
CACHE:
images/logo1.png
images/logo2.png
images/logo3.png

Cache aktualisieren

Sobald eine Anwendung offline ist, bleibt sie im Cache, bis einer der folgenden Schritte eintritt:

  1. Der Nutzer löscht den Datenspeicher seines Browsers für Ihre Website.
  2. Die Manifestdatei wird geändert. Hinweis: Das Aktualisieren einer im Manifest aufgeführten Datei bedeutet nicht, dass der Browser diese Ressource noch einmal im Cache speichert. Die Manifestdatei selbst muss geändert werden.

Cache-Status

Das window.applicationCache-Objekt ist Ihr programmatischer Zugriff auf den App-Cache des Browsers. Das Attribut status ist hilfreich, um den aktuellen Status des Cache zu prüfen:

var appCache = window.applicationCache;

switch (appCache.status) {
case appCache.UNCACHED: // UNCACHED == 0
return 'UNCACHED';
break;
case appCache.IDLE: // IDLE == 1
return 'IDLE';
break;
case appCache.CHECKING: // CHECKING == 2
return 'CHECKING';
break;
case appCache.DOWNLOADING: // DOWNLOADING == 3
return 'DOWNLOADING';
break;
case appCache.UPDATEREADY:  // UPDATEREADY == 4
return 'UPDATEREADY';
break;
case appCache.OBSOLETE: // OBSOLETE == 5
return 'OBSOLETE';
break;
default:
return 'UKNOWN CACHE STATUS';
break;
};

Wenn Sie programmatisch nach Aktualisierungen des Manifests suchen möchten, rufen Sie zuerst applicationCache.update() auf. Dadurch wird versucht, den Cache des Nutzers zu aktualisieren. Dazu muss die Manifestdatei geändert worden sein. Wenn sich das applicationCache.status schließlich im Status UPDATEREADY befindet, wird durch das Aufrufen von applicationCache.swapCache() der alte Cache gegen den neuen Cache ausgetauscht.

var appCache = window.applicationCache;

appCache.update(); // Attempt to update the user's cache.

...

if (appCache.status == window.applicationCache.UPDATEREADY) {
appCache.swapCache();  // The fetch was successful, swap in the new cache.
}

Die gute Nachricht: Dies lässt sich automatisieren. Wenn du Nutzer auf die neueste Version deiner Website aktualisieren möchtest, lege einen Listener fest, der das updateready-Ereignis beim Seitenaufbau überwacht:

// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {

window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
    // Browser downloaded a new app cache.
    if (confirm('A new version of this site is available. Load it?')) {
    window.location.reload();
    }
} else {
    // Manifest didn't changed. Nothing new to server.
}
}, false);

}, false);

AppCache-Ereignisse

Erwartungsgemäß werden zusätzliche Ereignisse verwendet, um den Cache-Status zu überwachen. Der Browser löst Ereignisse für Dinge wie den Downloadfortschritt, das Aktualisieren des App-Cache und Fehlerbedingungen aus. Mit dem folgenden Snippet werden Ereignis-Listener für jeden Typ von Cache-Ereignis eingerichtet:

function handleCacheEvent(e) {
//...
}

function handleCacheError(e) {
alert('Error: Cache failed to update!');
};

// Fired after the first cache of the manifest.
appCache.addEventListener('cached', handleCacheEvent, false);

// Checking for an update. Always the first event fired in the sequence.
appCache.addEventListener('checking', handleCacheEvent, false);

// An update was found. The browser is fetching resources.
appCache.addEventListener('downloading', handleCacheEvent, false);

// The manifest returns 404 or 410, the download failed,
// or the manifest changed while the download was in progress.
appCache.addEventListener('error', handleCacheError, false);

// Fired after the first download of the manifest.
appCache.addEventListener('noupdate', handleCacheEvent, false);

// Fired if the manifest file returns a 404 or 410.
// This results in the application cache being deleted.
appCache.addEventListener('obsolete', handleCacheEvent, false);

// Fired for each resource listed in the manifest as it is being fetched.
appCache.addEventListener('progress', handleCacheEvent, false);

// Fired when the manifest resources have been newly redownloaded.
appCache.addEventListener('updateready', handleCacheEvent, false);

Wenn die Manifestdatei oder eine darin angegebene Ressource nicht heruntergeladen wird, schlägt die gesamte Aktualisierung fehl. Sollte ein solcher Fehler auftreten, verwendet der Browser weiterhin den alten Anwendungscache.

Verweise