[HTML5と関連API] アプリケーションキャッシュのサンプル

アプリケーションキャッシュを使用して、オフライン(ネットワークに接続されていない)環境でも閲覧ができるページのサンプルを作成してみた。

2010年10月時点で、Firefox3.6、Safari5.0、Chrome6.0にて動作確認

アプリケーションキャッシュ

アプリケーションキャッシュとは、Webアプリケーション を構成しているすべてのリソース(HTML/CSS/JavaScript/画像ファイル)をローカルにキャッシュしておくことで、ユーザがネットワークに接続していなくても Webアプリケーション を利用できるようにするための仕様である。

demo1 は、アプリケーションキャッシュの最もスタンダードとなる使用方法の例で、オンラインの状態で1度 demo1ページ へアクセスすれば、(この時、Firefoxの場合はページ上部に「このサイトはオフライン作業用データの保存を求めています」というメッセージが表示されるので、許可する必要がある)ネットワークに接続していない状態で再度同じURLへアクセスしてみても、オンライン時と変わらずにページが表示されるはずだ。(PCならLANケーブルを抜く、iPhoneなら機内モードにするなどで検証できる)

キャッシュマニフェスト

これらの動作は、「キャッシュマニフェスト」と呼ばれるファイルの作成と、html要素 が持「manifest」属性に該当のマニフェストファイルのパスを指定することだけで実現できる。
キャッシュマニフェストとは、キャッシュするリソースを列挙することを主目的としたファイルで、このファイル内に、一定のルールに従ってキャッシュすべきファイルやキャッシュしてはいけないファイル(必ずオンラインでのアクセスが必要なページなど)を指定する。

CACHE MANIFEST

index.html
style.css
scripts.js
 :
キャッシュするファイルを列挙
 :

詳細な記述ルールについては次の機会に記載したい。

尚、マニフェストファイルは MIMEタイプ を「text/cache-manifest」にする必要があるため、Apache の設定や .htaccess を使用するなどして、キャッシュマニフェストとして使用するファイルと MIMEタイプ を適切に対応させなければいけない。
本サンプルでは、キャッシュマニフェストを「cache.manifest」というファイル名にし、.htaccess を使用して「.manifest」という拡張子のファイルを「text/cache-manifest」という MIMEタイプ に関連付けている。

AddType text/cache-manifest .manifest

作成したキャッシュマニフェストとそれを使用するページを関連付けるには、以下のようにマニフェストファイルのパスを html要素 の manifest属性 に指定するだけでよい。

<html lang="ja" manifest="cache.manifest">
 :
</html>

本サイトでは index.html とマニフェストファイルを同階層に配置しているため、manifest属性 にキャッシュマニフェストのファイル名のみ指定している。

window.applicationCache

demo2 は、アプリケーションキャッシュを使用してローカルへファイルをキャッシュしている状況を、JavaScript を使用してページ上に表示している例である。
キャッシュするために行っている事は demo1 と基本的には変わらないが、JavaScript から、「window.applicationCache」というオブジェクトを介してキャッシュに関するイベントを監視し、イベント通知があれば、その内容をページ上に表示するようにしている。

アプリケーションキャッシュから発生するイベントには下記のようなものがある。

checkingThe user agent is checking for an update, or attempting to download the manifest for the first time. This is always the first event in the sequence.
noupdateThe manifest hadn't changed.
downloadingThe user agent has found an update and is fetching it, or is downloading the resources listed by the manifest for the first time.
progressThe user agent is downloading resources listed by the manifest.
cachedThe resources listed in the manifest have been downloaded, and the application is now cached.
updatereadyThe resources listed in the manifest have been newly redownloaded, and the script can use swapCache() to switch to the new cache.
obsoleteThe manifest was found to have become a 404 or 410 page, so the application cache is being deleted.
errorThe manifest was a 404 or 410 page, so the attempt to cache the application has been aborted.
The manifest hadn't changed, but the page referencing the manifest failed to download properly.
A fatal error occurred while fetching the resources listed in the manifest.
The manifest changed while the update was being run.

これを利用し、demo2 では、以下のようにキャッシュ状況を可視化している。

window.applicationCache.addEventListener('checking', function() {
  document.getElementById('output').innerHTML = '更新のチェック中...';
}, false);
window.applicationCache.addEventListener('noupdate', function() {
  document.getElementById('output').innerHTML = '更新はありません。';
}, false);
window.applicationCache.addEventListener('downloading', function() {
  document.getElementById('output').innerHTML = 'ダウンロード中...<img src="common/images/loading.gif" alt="loading" width="16" height="16">';
}, false);
window.applicationCache.addEventListener('cached', function() {
  document.getElementById('output').innerHTML = 'すべてのリソースがキャッシュ済みです。';
}, false);
window.applicationCache.addEventListener('error', function() {
  document.getElementById('output').innerHTML = 'エラーが発生しました。';
}, false);

表示速度の改善

iPhone や Android といったスマートフォンでは、以前と比べて改善されてきているとはいえ、やはりネットワークからのファイル読み取り速度には限界があるため、サイトの表示速度で葛藤することは多いかと思う。そんな時にアプリケーションキャッシュを使用することで、サイト表示速度を向上できるという効果も大きな見どころである。(もちろんスマートフォンに限った話ではないが)
サイトTOPページ、若しくは、ユーザが最も頻繁に使用するページだけでも、アプリケーションキャッシュによってローカル上に保存させておくことで、ユーザのページ表示待ちストレスのかなりの減少が期待できるのではないだろうか。

キャッシュの更新について

アプリケーションキャッシュの対象としているページについては、一度キャッシュされたリソースについては、次回からはネットワークアクセスが行われないため、通常の運用方法のように、更新したファイルをサーバ上にアップロードするだけでは変更を反映することはできない。このため、アプリケーションキャッシュを使用しているページについては、リソースの更新に合わせてキャッシュマニフェストも変更する必要がある。
マニフェストが更新されたかどうかはファイル内容の厳密な比較で行われるため、以下のようにマニフェスト内にコメントとしてバージョンを記載しておき、リソースの変更があった場合は、同時にそのバージョンも変更することによって、ブラウザに対してリソースの内容が変化したと通知する方法が運用し易いと考えられる。

CACHE MANIFEST

# Version: 201010111817

index.html
style.css
scripts.js
 :
キャッシュするファイルを列挙
 :

"#"から始まる行はコメントとして認識される。

Webといえば「ネットにつながっていれば使える」という発想に駆られるが、その常識は HTML5 と関連APIのリリースによって覆るかもしれない。
Webアプリケーション全体をキャッシュするような大きなデータを扱うにはまだ色々と問題があるかもしれないが、例えばメモ帳のような、個人的なデータを扱う程度の機能であれば、オンラインとオフラインの差が消えていくかもしれない。

トラックバックURL

http://mashimonator.weblike.jp/mt/mt-tb.cgi/155

コメント投稿フォーム