Zgodnie z zapowiedzią z poprzedniego wpisu, dziś cache aplikacji w HTML5 (ang. Application Cache API)!

Cache’owanie aplikacji pozwala na przetrzymywanie elementów strony www na komputerze użytkownika (oczywiście po pierwszych odwiedzinach strony). Dzięki temu możliwe jest:

  • przeglądanie strony w trybie offline
  • przyspieszenie ładowania strony - elementy które się nie zmieniły od ostatnich odwiedzin nie muszą być pobierane ponownie
  • zmniejszenie ilości pobieranych danych z serwera - z tego samego powodu co wyżej ;)

Manifest cache’owania

Aby włączyć cache’owanie na stronie www, należy zadeklarować plik manifestu cache’owania za pomocą atrybutu manifest znacznika <html> - tak jak w poniższym przykładzie:

<!DOCTYPE HTML>
<html manifest="manifest.appcache">
...
</html>

Należy pamiętać, że cache’owanie będzie działać tylko na stronach ze zdefiniowanym plikiem manifestu. Ponadto ścieżka do tego pliku może być zarówno typu ‘relative’ jak i ‘absolute’. Plik ten może mieć jakiekolwiek rozszerzenie (najczęściej stosuje się takie rozszerzenie jak w przykładzie - *.appcache), jednak na serwerze musi mieć on ustawiony odpowiedni typ MIME, a konkretnie ‘text/cache-manifest’.

Przejdźmy zatem do samego pliku manifestu. Plik ten określa jakie dokładnie elementy strony mają być cache’owane - odpowiednie wartości umieszcza się w trzech dostępnych sekcjach:

  • CACHE MANIFEST - pliki i zasoby podane w tej sekcji zostaną dodane do cache’u po ich pierwszym pobraniu z serwera
  • NETWORK - pliki znajdujące się tutaj, nie będą nigdy dodane do cache’u
  • FALLBACK - pliki podane w tej sekcji posiadają stronę “awaryjną”, która wyświetli się jeśli strona nie będzie dostępna

CACHE MANIFEST

Przejdźmy do przykładów poszczególnych sekcji:

CACHE MANIFEST
/style.css
/logo.png
/scripts.js

Wymienione w powyższej sekcji pliki, zostaną przez przeglądarkę zachowane i będą dostępne nawet jeśli użytkownik nie będzie podłączony do internetu.

NETWORK

NETWORK:
login.aspx

W tym przypadku, informujemy przeglądarkę, aby nigdy nie pobierała zawartości strony ‘‘login.aspx’ tylko zawsze pobierała ją z serwera. Jeśli użytkownik nie będzie miał połączenia z internetem, nie będzie mógł wejść na tę stronę.

FALLBACK

FALLBACK:
/html/ /error.html

W powyższy sposób możemy zdefiniować, że strona ‘error.html’ ma zostać wyświetlona, gdy którykolwiek z plików znajdujących się w ‘/html/’ nie będzie dostępny. W tym przypadku zawsze najpierw podajemy sprawdzany zasób a następnie stronę “awaryjną”.

No dobrze, mamy już zdefiniowany plik manifestu, wszystkie oczekiwane zasonby zostały dodane do cache’u. Co jeśli teraz zmienimy jeden z obrazków lub skrypt JavaScript? Musimy o tym przeglądarkę poinformować. Sposobem na to jest kod z poniższego przykładu:

CACHE MANIFEST
# 2013-02-10 v1.1.0
/style.css
/logo.gif
/scripts.js

NETWORK:
login.aspx

FALLBACK:
/html/ /offline.html

Pliki znajdujące się wcache’u mogą zostać pobrane tylko w trzech przypadkach: użytkownik wyczyści cache ręcznie, cache zostanie zmodyfikowany ręcznie z poziomu JavaScript lub gdy plik manifestu zostanie zmieniony. Ten ostatni efekt uzyskaliśmy właśnie w naszym przykładzie - w drugiej linii widać komentarz zawierający datę modyfikacji i wersję - to wystarczy by przeglądarka uznała, że manifest się zmienił i żeby pobrała pliki jeszcze raz.

Dostęp do AppCache z poziomu JavaScript

Obiekt ‘window’ poprzez właściwość ‘applicationCache’ umożliwia dostęp do cache’u aplikacji z poziomu skryptu JavaScript. Nie jest to jednak pełen dostęp do informacji zdefiniowanych w pliku manifestu. Możemy jednak śledzić aktualny status cache’u aplikacji (przykład ze strony html5rocks.com):

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;
};

W powyższym przykładzie możemy zobaczyć jak można się odwołać do obiektu ‘applicationCache’ oraz jakie statusy tego obiektu możemy śledzić.

Istnieje też możliwość wymuszenia przeładowania cache’u (przykład ponownie z html5rocks.com):

var appCache = window.applicationCache;

appCache.update(); // próba przeładowania cache'u

...

if (appCache.status == window.applicationCache.UPDATEREADY) {
  // pobieranie cache'u udane, zamień stary cache na nowy
  appCache.swapCache();  
}

W trzeciej linii mamy próbę przeładowania cache’u - jednak nastąpi to tylko jeśli cache uległ zmianie w stosunku do tego jaki jest obecnie wczytany. Następnie sprawdzamy status cache’u i jeśli jest w stanie ‘UPDATEREADY’ (czyli nastąpiła zmiana manifestu) możemy dokonać zamiany starych plików na nowe (linia ósma).

Jak widać, z poziomu JavaScript nie mamy możliwości “grzebania” w obecnie załadowanym cache’u. Możemy jedynie z jego poziomu sprawdzić czy nastąpiły jakieś zmiany w pliku manifestu na serwerze i zareagować na nie.

Cache aplikacji w HTML5 - podsumowanie

Niewątpliwie wprowadzenie cache aplikacji w HTML5 to duży skok jakościowy. Widać jednak, że powinno się uważać na to co jest cache’owane - przeglądarka nie będzie wiedziała o zmianach w plikach, które cache’uje do póki nie zostanie zmieniony plik manifestu. Jeśli o tym zapomnimy, możemy niepotrzebnie się naszukać, dlaczego nasza zmiana w skrypcie czy grafice nie działa…

To tyle na temat Cache aplikacji w HTML5. Następny odcinek poświęcony będzie API geolokacyjnemu dostępnemu w HTML5.