Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?
@takushi-m@github

ServiceWorkerを触ってみる

More than 3 years have passed since last update.

https://dev.to/mizchi/-devto--b5
の記事を読んでServiceWorkerってどんな仕組みなんだろうということが気になって調べてみました。

https://developers.google.com/web/fundamentals/primers/service-workers/?
によると
- domは触れない
- ネットワークプロキシ的なことがコードで書ける

らしいです。なのでAPIのレスポンスをネットワークアクセスなしにキャッシュしたりできると。
ほぼ参考文献ままですがコード書いてみました。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <h1>sw test</h1>

    <input id="url" type="text" name="" value="">
    <button id="add" type="button" name="button">add</button>
    <div id="list">
    </div>
    <script type="text/javascript">
    if ("serviceWorker" in navigator) {
      navigator.serviceWorker.register("/sw.js").then(function(registration) {
        console.log("success", registration.scope);
      }).catch(function(err) {
        console.log("error", err);
      });
    }

    var addBtn = document.querySelector("#add");
    addBtn.addEventListener("click", function() {
      var url = document.querySelector("#url").value;
      fetch("/resp/"+url)
      .then(function(resp) {
        return resp.json();
      })
      .then(function(data) {
        html = "";
        data.list.forEach(function(item) {
          html += "<p>"+item.name+"</p>";
        });
        document.querySelector("#list").innerHTML = html;
      });
    });
    </script>
  </body>
</html>
sw.js
var CACHE_NAME = "my-site-cache-v1";

self.addEventListener("fetch", function(event) {
  event.respondWith(
    caches.open(CACHE_NAME).then(function(cache) {
      return cache.match(event.request).then(function(resp) {
        if(resp) {
          return resp;
        }
        return fetch(event.request.clone()).then(function(resp) {
          if (resp.status<400 && (resp.url.indexOf("a.json")>=0)) {
            cache.put(event.request, resp.clone());
          }
          return resp;
        });
      });
    })
  );
});

respディレクトリ以下に以下の形式のjsonをモックとして置く

a.json
{
  "list": [
    {"name": "a1"},
    {"name": "a2"}
  ]
}

  1. navigator.serviceWorker.register でserviceWorkerの登録ができます。すでに登録されている場合はそれが使われる
  2. CACHE_NAMEの値をキーにしてAPIのレスポンスをキャッシュする。キャッシュする条件はレスポンスオブジェクトから好きに設定できる(今回の場合はa.jsonはしかキャッシュしないようにした
  3. API呼び出し側はキャッシュされているかどうかは気にせずレスポンスを使えばいい。なので、serviceWorkerが使えない場合でも正常に動く

上記を試したときのchrome devtoolのnetwork
image.png

枠で囲った部分が1リクエストあたりに表示される。a.jsonを取得するときには二回目以降は「from ServiceWorker」となっているが、b.jsonはsw.jsが取得してきたものが渡されている。sw.jsがAPIを呼び出すログも出力されているのでキャッシュされているかどうかを判断ここで判断できる(はず)。

参考文献

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
0
Help us understand the problem. What is going on with this article?