6

どのようなキャッシュ戦略を使用していますか? Offline Cookbook を読みましたが、使用する最も簡単な戦略は、静的コンテンツをキャッシュし、API 呼び出しを除外することです。

この戦略は次のようになります。

  1. リクエストがすでにキャッシュにあるかどうかを確認する
  2. リクエストとレスポンスのペアをキャッシュに追加しない場合
  3. 応答を返す

サーバー側のファイルが変更された場合、キャッシュを更新する方法は? 現在、クライアントは常にキャッシュされた結果を取得します。

これが私のキャッシュ戦略のコードです:

// You will need this polyfill, at least on Chrome 41 and older.
importScripts("serviceworker-cache-polyfill.js");

var VERSION = 1;

var CACHES = {
    common: "common-cache" + VERSION
};

// an array of file locations we want to cache
var filesToCache = [
    "font-cache.html",
    "script.js",
];

var neededFiles = [
    "index.html"
];

var errorResponse = function() {

    return new Response([
            "<h2>Failed to get file</h2>",
            "<p>Could not retrive response from cache</p>"
        ].join("\n"),
        500
    );
};

var networkFetch = function(request) {

    return fetch(request).then(function(response) {

        caches.open(CACHES["common"]).then(function(cache) {

            return cache.put(request, response);
        });

    }).catch(function() {
        console.error("Network fetch failed");
        return errorResponse();
    });
}

this.addEventListener("install", function(evt) {
    evt.waitUntil(
        caches.open(CACHES["common"]).then(function(cache) {

            // Cache before
            cache.addAll(filesToCache);
            return cache.addAll(neededFiles);
        })
    );
});

this.addEventListener("activate", function(event) {

    var expectedCacheNames = Object.keys(CACHES).map(function(key) {
        return CACHES[key];
    });

    console.log("Activate the worker");

    // Active worker won"t be treated as activated until promise resolves successfully.
    event.waitUntil(
        caches.keys().then(function(cacheNames) {
            return Promise.all(
                cacheNames.map(function(cacheName) {
                    if (expectedCacheNames.indexOf() ===
                        -1) {
                        console.log(
                            "Deleting out of date cache:",
                            cacheName);

                        return caches.delete(cacheName);
                    }
                })
            );
        })
    );
});

self.addEventListener("fetch", function(event) {
    console.log("Handling fetch event for", event.request.url);

    event.respondWith(

        // Opens Cache objects
        caches.open(CACHES["common"]).then(function(cache) {
            return cache.match(event.request).then(function(
                response) {

                if (response) {
                    console.log("Found response in cache", response);

                    return response;
                } else {

                    return networkFetch(event.request);
                }
            }).catch(function(error) {

                // Handles exceptions that arise from match() or fetch().
                console.error(
                    "  Error in fetch handler:",
                    error);

                return errorResponse();
            });
        })
    );
});

4

3 に答える 3

4

Jeff Posnick の優れたソリューションであるsw-precacheに慣れるかもしれません。
そこで使用される戦略は次のとおりです。

  1. Gulp はチェックサムを含む Service Worker ファイルを生成しています
  2. Service Worker が登録されている (独自のチェックサムを使用)
  3. ファイルが追加/更新された場合、SW ファイルが変更されます
  4. 次回の訪問で、SW はそのチェックサムが異なることを確認するため、更新されたファイルで再度登録します。

好きな方法でバックエンドでこのフローを自動化できます:)

彼はこの記事でそれをよりよく説明しました

于 2015-05-29T13:25:55.940 に答える
2

これは、キャッシュに使用するコードです。リソースを取得し、キャッシュして提供します。

this.addEventListener("fetch", function(event) {
  event.respondWith(
    fetch(event.request).then(function(response) {
      return caches.open("1").then(function(cache) {
        return cache.put(event.request, response.clone()).then(function() {
          return response
        })
      })
    }).catch(function() {
      return caches.match(event.request)
    })
  )
})
于 2015-05-29T19:27:25.073 に答える