6
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

posted at

PWA: Workbox Precaching 和訳 (その2)

プリキャッシング

参照元ページ: https://developers.google.com/web/tools/workbox/modules/workbox-precaching

プリキャッシュされた内容のレスポンスを返す

workbox.precaching.precacheAndRoute()もしくはworkbox.precaching.addRoute()はプリキャッシュされたファイルパス(URL)と一致するrouteを作成します。

このレスポンスのストラテジーはcache-firstと呼ばれます。cache-firstでは、ネットワークからのレスポンスの代わりに、プリキャッシュされたコンテンツのレスポンスを返す仕様です(なんらかの不測の事態によりキャッシュからレスポンスが返せない時を除いて)。

workbox.precaching/precacheAndRoute()もしくはworkbox.precaching.addRoute()を呼ぶ順番は重要です。これらは通常、workbox.routing.registerRoute()で追加のルーティングを登録する前にサービスワーカー内で呼ぶ必要があります。

プリキャッシュリストの説明

workbox-precachingは文字列の配列かオブジェクトの配列を使います。例えば下記のように。


workbox.precaching.precacheAndRoute([
  '/styles/example.ac29.css', //文字列
  {
     url: '/index.html'
     revision: 'as46',
  } //オブジェクト
])

workbox.precachingに使われるリストは"リビジョニング"の情報と紐付けられた一式のURLを参照します。上記の例ですと、文字列で渡された/styles/example.ac29.cssのrevisionはURL自身となります。この方法により、すべてのブラウザで長期的にこれらのURLをキャッシュすることができます。このように各ファイルをリビジョニングすることで、プリキャッシュするファイルのリストを作ることができます。(補足: 文字列を渡す場合はファイル名を動的にハッシュ付きで生成することを想定しているようです)

URLにリビジョン情報(バージョン情報)を持たないファイルに対しては、1つのファイルの情報をオブジェクトにして、revisionプロパティを与える必要があります。これにより、いつファイルが更新されたかをworkbox-precachingが知ることができます。

Workboxはこのリストを生成するツールを提供しています。

  • workbox-build: npmモジュールでgulpやnpm scriptで使用できます
  • workbox-webpack-plugin: webpackユーザはこのプラグインを使えます
  • workbox-cli: これを使ってプリキャッシュリストを生成することも可能です

これらのツールを使うことで簡単にリストを作成することができますが、あなた自身で生成することも可能です。その場合は、ファイルの更新があるたびに、一意のrevisionプロパティを与えなくてはいけないことに注意してください。


// Revisioned files added via a glob
workbox.precaching.precache([
  '/styles/example-1.abcd.css',
  '/styles/example-2.1234.css',
  '/scripts/example-1.abcd.js',
  '/scripts/example-2.1234.js',
]);

// Precache entries from workbox-build or somewhere else
workbox.precaching.precache([
  {
    url: '/index.html',
    revision: 'abcd',
  }, {
    url: '/about.html',
    revision: '1234',
  }
]);

// Add Precache Route
workbox.precaching.addRoute();

プリキャッシュファイルに対するリクエスト

workbox.precacheingが行う素晴らしいことはネットワークへのリクエストを操作してプリキャッシュファイルのものと一致させることです。これはよくあるウェブのお作法を取り入れています。

例えば、/に対するリクエストは/index.htmlに置き換えてレスポンスが送られます。

下記にworkbox.precachingが行う、操作の一覧を記載します。

URLパラメータを無視する

検索パラメータ付きのリクエストは特定の値もしくはすべての値を削除した形に置き換えられます。

デフォルトでは、utm_の値は削除され、/?utm_=123のようなリクエストは/に変更されます。

ignoreUrlParametersMatchingに渡す値によって何のパラメータを削除したいか指定できます。

workbox.precaching.precacheAndRoute(
  [
    '/styles/index.0c9a31.css',
    '/scripts/main.0d5770.js',
    { url: '/index.html', revision: '383676' },
  ],
  {
    ignoreUrlParametersMatching: [/.*/]
  }
);

ディレクトリインデックス

/で終わるリクエストは、末尾にindex.htmlが付与されます。つまり/でURLを指定した場合は/index.htmlのキャッシュを見にいくことになります。

この挙動はdirectoryIndexnullを渡すことで無効化できます。

workbox.precaching.precacheAndRoute(
  [
    '/styles/index.0c9a31.css',
    '/scripts/main.0d5770.js',
    { url: '/index.html', revision: '383676' },
  ],
  {
    directoryIndex: null,
  }
);

Clean URL

もしリクエストがプリキャッシュのものと一致せず失敗した場合は、"clean"(もしくは"pretty") URLsをサポートしており、末尾に.htmlを付与します。これにより/aboutのリクエストは/about.htmlとマッチすることになります。cleanUrlsfalseを与えることで無効化できます。

workbox.precaching.precacheAndRoute(
  [
    '/styles/index.0c9a31.css',
    '/scripts/main.0d5770.js',
    { url: '/index.html', revision: '383676' },
  ],
  {
    cleanUrls: false,
  }
);

カスタムで操作する

飛んできたリクエストをカスタムで操作したい場合はurlManipulationを使用できます。これはコールバックでマッチするオプションを渡すことできます。

workbox.precaching.precacheAndRoute(
  [
    '/styles/index.0c9a31.css',
    '/scripts/main.0d5770.js',
    { url: '/index.html', revision: '383676' },
  ],
  {
    urlManipulation: ({url}) => {
      ...
      return [alteredUrlOption1, alteredUrlOption2, ...];
    }
  }
);

上級者の使い方

PrecacheControllerを直接使う

デフォルトでは、workbox-precachinginstallactivateリスナーを設定してくれます。しかし、サービスワーカーに慣れ親しんだディベロッパーにとってはこの挙動は必ずしも望ましいとは限りません。

PrecacheControllerを使用することでファイルのプリキャッシュのタイミングやキャッシュファイルの削除などを自由に決めることが可能です。


const precacheController = new workbox.precaching.PrecacheController();
precacheController.addToCacheList([
  '/styles/example-1.abcd.css',
  '/styles/example-2.1234.css',
  '/scripts/example-1.abcd.js',
  '/scripts/example-2.1234.js',
]);

precacheController.addToCacheList([
  {
    url: '/index.html',
    revision: 'abcd',
  }, {
    url: '/about.html',
    revision: '1234',
  }
]);

self.addEventListener('install', (event) => {
  event.waitUntil(precacheController.install());
});
self.addEventListener('activate', (event) => {
  event.waitUntil(precacheController.cleanup());
});
self.addEventListener('fetch', (event) => {
  event.respondWith(caches.match(event.request).then(...));
});
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
Sign upLogin
6
Help us understand the problem. What are the problem?