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

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 - アプリケーションのサービス ワーカー ファイル

3. オフライン テスト

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

  1. Chrome DevTools を開く
  2. [アプリケーション] タブに切り替えます
  3. [Service Workers] セクションに切り替えます。
  4. [オフライン] チェックボックスをオンにする
  5. Chrome DevTools を閉じずにページを更新する

Chrome デベロッパー ツールの [Application] タブが開かれ、[Service Workers] が選択され、[Offline] チェックボックスがオンになっている

サイトのテストが完了し、オフラインで読み込みに失敗することが確認できたら、オンライン機能をいくつか追加しましょう。[オフライン] チェックボックスをオフにして、次の手順に進みます。

4. YouTube の外で交流する

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

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);
    }),
  );
});

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

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

説明

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

サービス ワーカーがサイトを制御すると、リクエストされたリソースはプロキシのようにサービス ワーカーを通過します。各リクエストはフェッチ イベントをトリガーします。このサービス ワーカーでは、キャッシュを検索して一致するリソースを探し、一致するリソースがあれば、キャッシュに保存されたリソースでレスポンスを返します。一致しない場合は、リソースが通常どおりリクエストされます。

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

5. 完了

サービス ワーカーとキャッシュ ストレージ API を使用してウェブアプリをオフラインにする方法について学習しました。

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