Service Worker Cache API の更新

Service Worker のキャッシュ API のかなりマイナーなアップデートに関して、この投稿を書くように依頼されました。記事自体が正当だとは思っていませんでしたが、長きにわたって議論を重ね、最終的にはじゃんけんゲームに行き着きました。私は負けたので、ここで紹介しましょう。

Chrome での Service Worker Cache API の実装に関する更新について、

あなたの声が聞こえません。先ほど、Chrome での Service Worker Cache API の実装に関する更新について、準備はよろしいですか?

(これを読むには、椅子に飛び乗り、「イエーイ!」と叫んでください。同時に投げ縄を振るふりをすることは任意ですが、推奨されます)。

cache.addAll が Chrome 46 で利用可能に

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

皮肉はさておき、cache.addAllキャッシュの「essentials」ポリフィルの最後の部分であり、不要になったため、これは実際には大きな問題です。

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 の配列と取得してキャッシュに追加します。これはトランザクション プロセスです。フェッチまたは書き込みのいずれかが失敗すると、オペレーション全体が失敗し、キャッシュは以前の状態に戻ります。これは、1 回の失敗が全体の失敗である、上記のようなインストール オペレーションに特に便利です。

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

Firefox のデベロッパー版ではすでにこの API をサポートしているため、他の Service Worker 実装でもこの API を使用できます。

ただし、それだけではありません。パイプラインでさらにキャッシュを改善する方法があります。

cache.matchAll が Chrome 47 でリリース

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

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

上記のコードは、/ に一致する mysite-static-v1 のすべてを取得します。個別にキャッシュできる場合(Vary ヘッダーが異なる場合など)は、URL ごとに複数のエントリを作成できます。

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 - キャッシュに保存されたレスポンスの var ヘッダーを無視します。

Firefox ではすでにこの機能がサポートされていますが、Ben Kelly さんは、Firefox にこれらすべてを導入したのが、いかに素晴らしいかを伝えましょう。

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

次回お会いしましょう。「キャッシュ API での実装内容」に関する新たな章でお会いしましょう。