プログレッシブ ウェブアプリ: オフライン

1. ようこそ

このラボでは、既存のウェブ アプリケーションをオフラインで動作するようにします。これは、最初のプログレッシブ ウェブ アプリのワークショップのコンパニオン Codelab シリーズの最初のものです。このシリーズには、さらに 7 つの Codelab があります。

学習内容

  • Service Worker を手動で作成する
  • 既存のウェブ アプリケーションに Service Worker を追加する
  • Service Worker と Cache Storage API を使用して、リソースをオフラインで使用できるようにする

必要な予備知識

  • 簡易 HTML と JavaScript

必要なもの

2. 準備

まず、この Codelab を完了するために必要なスターター コードをクローンまたはダウンロードします。

リポジトリをクローンする場合は、starter ブランチにいることを確認してください。ZIP ファイルにも、そのブランチのコードが含まれています。

このコードベースには Node.js 14 以降が必要です。コードが使用可能になったら、コードのフォルダのコマンドラインから npm ci を実行して、必要な依存関係をすべてインストールします。次に、npm start を実行して、Codelab の開発サーバーを起動します。

ソースコードの README.md ファイルには、配布されたすべてのファイルの説明が記載されています。また、この Codelab で使用する主な既存のファイルは次のとおりです。

主なファイル

  • js/main.js - メイン アプリケーションの JavaScript ファイル
  • service-worker.js - アプリケーションの Service Worker ファイル

3. オフラインでテストする

変更を加える前に、ウェブ アプリが現在オフラインで動作しないことをテストしてみましょう。これを行うには、パソコンをオフラインにしてウェブ アプリを再読み込みします。Chrome を使用している場合は、次の手順を行います。

  1. Chrome デベロッパー ツールを開く
  2. [Application] タブに切り替える
  3. [Service Workers] セクションに切り替える
  4. [Offline] チェックボックスをオンにする
  5. Chrome Dev Tools を閉じずにページを更新する

Chrome DevTools の [Application] タブが開かれ、[Service Workers] の [Offline] チェックボックスがオンになっている

サイトをテストし、オフラインで読み込めないことを確認したら、オンライン機能を追加します。[Offline] チェックボックスをオフにして、次のステップに進みます。

4. オフラインにする

基本的な Service Worker を追加します。これは、Service Worker の登録とリソースのキャッシュという 2 つのステップで行われます。

Service Worker を登録する

空の Service Worker ファイルがすでに存在するため、変更が反映されるように、アプリケーションに登録しましょう。これを行うには、次のコードを js/main.js の先頭に追加します。

// Register the service worker
if ('serviceWorker' in navigator) {
  // Wait for the 'load' event to not block other work
  window.addEventListener('load', async () => {
    // Try to register the service worker.
    try {
      // Capture the registration for later use, if needed
      let reg;

      // Use ES Module version of our Service Worker in development
      if (import.meta.env?.DEV) {
        reg = await navigator.serviceWorker.register('/service-worker.js', {
          type: 'module',
        });
      } else {
        // In production, use the normal service worker registration
        reg = await navigator.serviceWorker.register('/service-worker.js');
      }

      console.log('Service worker registered! 😎', reg);
    } catch (err) {
      console.log('😥 Service worker registration failed: ', err);
    }
  });
}

説明

このコードは、ページが読み込まれたら、サイトが Service Worker をサポートしている場合にのみ、空の service-worker.js Service Worker ファイルを登録します。

リソースをプリキャッシュする

ウェブ アプリをオフラインで動作させるには、ブラウザがネットワーク リクエストに応答し、リクエストのルーティング先を選択できる必要があります。これを行うには、次のコードを service-worker.js に追加します。

// Choose a cache name
const cacheName = 'cache-v1';
// List the files to precache
const precacheResources = ['/', '/index.html', '/css/style.css', '/js/main.js', '/js/app/editor.js', '/js/lib/actions.js'];

// When the service worker is installing, open the cache and add the precache resources to it
self.addEventListener('install', (event) => {
  console.log('Service worker install event!');
  event.waitUntil(caches.open(cacheName).then((cache) => cache.addAll(precacheResources)));
});

self.addEventListener('activate', (event) => {
  console.log('Service worker activate event!');
});

// When there's an incoming fetch request, try and respond with a precached resource, otherwise fall back to the network
self.addEventListener('fetch', (event) => {
  console.log('Fetch intercepted for:', event.request.url);
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      if (cachedResponse) {
        return cachedResponse;
      }
      return fetch(event.request);
    }),
  );
});

ブラウザに戻り、プレビュー タブを閉じてから再度開きます。Service Worker のさまざまなイベントに対応する console.log が表示されます。

次に、もう一度オフラインにしてサイトを更新します。オフラインでも読み込まれることがわかります。

説明

Service Worker の install イベント中に、Cache Storage API を使用して名前付きキャッシュが開きます。precacheResources で指定されたファイルとルートは、cache.addAll メソッドを使用してキャッシュに読み込まれます。これは、必要なときやリクエストされたときにキャッシュに保存するのではなく、インストール時にファイルのセットを事前にキャッシュに保存するため、プリキャッシュと呼ばれます。

Service Worker がサイトを制御すると、リクエストされたリソースはプロキシのように Service Worker を通過します。各リクエストは fetch イベントをトリガーします。この Service Worker では、キャッシュで一致するものが検索され、一致するものがあれば、キャッシュに保存されたリソースで応答します。一致するものがない場合は、リソースが通常どおりリクエストされます。

リソースをキャッシュに保存すると、ネットワーク リクエストを回避してアプリをオフラインで動作させることができます。これで、アプリはオフライン時にステータス コード 200 で応答できるようになりました。

5. 完了

Service Worker と Cache Storage API を使用してウェブ アプリをオフラインにする方法を学習しました。

このシリーズの次の Codelab は、Workbox の使用です。