Service Worker Cache API の更新

Service Worker キャッシュ API の比較的小さな更新について、この投稿を書くよう依頼されました。わざわざ記事を書くほどのものではないと思っていたのですが、長い議論の末、最終的にじゃんけんに決着がつき、負けたので、ここに書くことにしました。

Chrome での実装が更新された Service Worker Cache API について、詳しく説明します。

声が聞こえません。Chrome でのサービス ワーカー キャッシュ API の実装に関する最新情報についてお話しします。

(椅子に飛び上がって「YEAHHH!」と叫んだら、読み進めてください。同時にロープを振り回すふりをするのも任意ですが、おすすめします)。

cache.addAll が Chrome 46 に導入されました

はい。正解です。キャッシュ!ドット すべて追加Chrome 46 です。

冗談はさておき、これは実際にはかなり大きな問題です。cache.addAllキャッシュの「必須」ポリフィルの最後の残りの部分であるため、不要になりました。

cache.addAll の仕組みは次のとおりです。

// when the browser sees this SW for the first time
self.addEventListener('install', function(event) {
    // wait until the following promise resolves
    event.waitUntil(
    // open/create a cache named 'mysite-static-v1'
    caches.open('mysite-static-v1').then(function(cache) {
        // fetch and add this stuff to it
        return cache.addAll([
        '/',
        '/css/styles.css',
        '/js/script.js',
        '/imgs/cat-falls-over.gif'
        ]);
    })
    );
});

addAll は、URL とリクエストの配列を受け取り、フェッチしてキャッシュに追加します。これはトランザクションです。取得または書き込みのいずれかが失敗すると、オペレーション全体が失敗し、キャッシュは以前の状態に戻ります。これは、単一の障害が全体的な障害となる上記のようなインストール オペレーションで特に役立ちます。

上記の例は Service Worker 内ですが、caches API はページからも完全にアクセスできます。

Firefox では、この API はすでにデベロッパー エディションでサポートされているため、他の Service Worker 実装とともにリリースされます。

キャッシュの改善はまだまだ続きます。

cache.matchAll が Chrome 47 に導入される

これにより、複数の一致を取得できます。

caches.open('mysite-static-v1').then(function(cache) {
    return cache.matchAll('/');
}).then(function(responses) {
    // …
});

上記の式では、/ に一致する mysite-static-v1 内のすべての値が取得されます。キャッシュでは、個別にキャッシュに保存できる URL ごとに複数のエントリを指定できます(異なる Vary ヘッダーがある場合など)。

Firefox ではすでにデベロッパー エディションでサポートされているため、他の Service Worker の実装とともにリリースされます。

キャッシュ クエリ オプションが Chrome に近日提供予定

標準的な取得ハンドラは次のとおりです。

self.addEventListener('fetch', function(event) {
    event.respondWith(
    caches.match(event.request).then(function(response) {
        return response || fetch(event.request);
    })
    );
});

/ がキャッシュに保存されていて、/ のリクエストが届いた場合、キャッシュから提供されます。ただし、/?utm_source=blahblahwhatever のリクエストがキャッシュから取得されない場合、この問題を回避するには、一致時に URL 検索文字列を無視します。

self.addEventListener('fetch', function(event) {
    event.respondWith(
    caches.match(event.request, {
        ignoreSearch: true
    }).then(function(response) {
        return response || fetch(event.request);
    })
    );
});

これで、/?utm_source=blahblahwhatever/ のエントリと照合されます。利用可能なオプションは次のとおりです。

  • ignoreSearch - リクエスト引数とキャッシュに保存されたリクエストの両方で、URL の検索部分を無視します。
  • ignoreMethod - リクエスト引数のメソッドを無視するため、POST リクエストがキャッシュ内の GET エントリと一致する可能性がある
  • ignoreVary - キャッシュに保存されたレスポンスの vary ヘッダーを無視する

Firefox ではすでに、この機能がサポートされています。これらの機能を Firefox に実装してくれた Ben Kelly に感謝の気持ちを伝えましょう。

Chrome でのキャッシュ クエリ オプションの実装については、crbug.com/426309 をご覧ください。

次回も「cache API に実装された機能」についてお話しします。