更新

PWA を公開しました。他のユーザーはブラウザから PWA を使用し、他のユーザーはデバイスに PWA をインストールします。アプリを更新するときは、おすすめの方法を適用して問題を回避することが重要です。

更新可能な内容:

  • アプリのデータ] をタップします。
  • アセットがすでにデバイスにキャッシュされている。
  • Service Worker ファイルまたはその依存関係。
  • マニフェスト メタデータ。

それぞれの要素に関するベスト プラクティスを確認しましょう。

データを更新する

IndexedDB に保存されているデータなどのデータを更新するには、Fetch、WebRTC、WebSocket API などのツールを使用できます。アプリがオフライン機能をサポートしている場合は、その機能をサポートするデータも常に最新の状態にしておいてください。

互換性のあるブラウザでは、ユーザーが PWA を開いたときだけでなく、バックグラウンドでもデータを同期できます。オプションは次のとおりです。

  • バックグラウンド同期: 失敗したリクエストを保存し、Service Worker からの同期を使用してリクエストを再試行します。
  • ウェブでの定期的なバックグラウンド同期: バックグラウンドで定期的に特定の時間にデータを同期します。これにより、ユーザーがアプリをまだ開いていなくても、アプリから最新のデータを提供できます。
  • バックグラウンド取得: PWA を閉じていても、サイズの大きいファイルをダウンロードします。
  • ウェブプッシュ: サーバーからメッセージを送信し、Service Worker を起動してユーザーに通知します。これは一般に「プッシュ通知」と呼ばれます。この API を使用するにはユーザーの権限が必要です。

これらの API はすべて Service Worker コンテキストから実行されます。現在のところ、この機能は Chromium ベースのブラウザ、Android、パソコンのオペレーティング システムでのみご利用いただけます。これらの API のいずれかを使用すると、Service Worker スレッドでコードを実行できます。たとえば、サーバーからデータをダウンロードしたり、IndexedDB データを更新したりできます。

アセットを更新しています

アセットの更新には、アプリのインターフェースのレンダリングに使用するファイル(HTML、CSS、JavaScript、画像など)に対する変更が含まれます。たとえば、アプリのロジックの変更、インターフェースの一部の画像、CSS スタイルシートの変更などです。

パターンを更新する

以下に、アプリのアップデートを処理する一般的なパターンを示します。このプロセスは、必要に応じていつでもカスタマイズできます。

  • フル アップデート: 小さな変更であっても、そのたびにキャッシュ コンテンツ全体が置き換えられます。このパターンは、デバイス固有のアプリがアップデートを処理する方法を模倣したもので、より多くの帯域幅を消費し、時間がかかります。
  • 変更済みアセットの更新: 前回の更新以降に変更されたアセットのみがキャッシュで置き換えられます。多くの場合、Workbox などのライブラリを使用して実装されます。これには、キャッシュされたファイルのリスト、ファイルのハッシュ表現、タイムスタンプの作成が含まれます。Service Worker はこの情報を使用して、このリストをキャッシュに保存されたアセットと比較し、更新するアセットを決定します。
  • 個々のアセットの更新: 各アセットは、変更が行われると個別に更新されます。アセットを個別に更新する例としては、配信の章で説明している古い再検証の戦略があります。

更新のタイミング

アップデートを確認して適用するための適切な時間を見つけることもおすすめします。次のようなオプションがあります。

  • Service Worker が起動したとき。現時点ではリッスンするイベントはありませんが、ブラウザはスリープ解除時に Service Worker のグローバル スコープ内のコードを実行します。
  • ブラウザがページを読み込んだ後、PWA のメイン ウィンドウのコンテキストで、アプリの読み込みが遅くならないようにします。
  • PWA がプッシュ通知を受信したときや、バックグラウンド同期が開始されたときなど、バックグラウンド イベントがトリガーされたとき。キャッシュを更新すると、ユーザーが次回アプリを開いたときにアセットの新しいバージョンが表示されます。

ライブ情報

また、アプリが開いている(ライブ)ときと閉じているときのどちらにアップデートを適用するかを選択することもできます。アプリを閉じるアプローチでは、アプリは新しいアセットをダウンロードしたものの、変更を加えず、次回の読み込み時に新しいバージョンを使用します。

ライブ アップデートでは、キャッシュ内のアセットが更新されるとすぐに、PWA によって現在の読み込みのアセットが置き換えられます。これは複雑なタスクであり、このコースでは扱いません。この更新の実装に役立つツールには、livereload-js と CSS アセット更新 CSSStyleSheet.replace() API があります。

Service Worker の更新

Service Worker またはその依存関係が変更されると、ブラウザは更新アルゴリズムをトリガーします。ブラウザは、キャッシュされたファイルとネットワークから送信されるリソースとをバイト単位で比較して、更新を検出します。

その後、ブラウザは新しいバージョンの Service Worker のインストールを試行します。新しい Service Worker は待機状態になります。詳しくは、Service Worker の章をご覧ください。新しいインストールでは、新しい Service Worker の install イベントが実行されます。このイベント ハンドラでアセットをキャッシュに保存している場合は、アセットも再キャッシュされます。

Service Worker の変更の検出

新しい Service Worker の準備ができてインストールされたことを検出するために、Service Worker 登録の updatefound イベントを使用します。このイベントは、新しい Service Worker がインストールを開始すると発生します。statechange イベントで状態が installed に変わるまで待つ必要があります。以下をご覧ください。

async function detectSWUpdate() {
  const registration = await navigator.serviceWorker.ready;

  registration.addEventListener("updatefound", event => {
    const newSW = registration.installing;
    newSW.addEventListener("statechange", event => {
      if (newSW.state == "installed") {
         // New service worker is installed, but waiting activation
      }
    });
  })
}

強制オーバーライド

新しい Service Worker はインストールされますが、デフォルトでは有効化を待機します。この待機により、新しいバージョンと互換性がない可能性がある古いクライアントが新しい Service Worker に引き継がれるのを防ぐことができます。

おすすめしませんが、新しい Service Worker はその待機期間をスキップして、すぐに有効化を開始できます。

self.addEventListener("install", event => {
   // forces a service worker to activate immediately
   self.skipWaiting();
  });

self.addEventListener("activate", event => {
  // when this SW becomes activated, we claim all the opened clients
  // they can be standalone PWA windows or browser tabs
  event.waitUntil(clients.claim());
});

controllerchange イベントは、現在のページを制御する Service Worker が変更されると起動されます。たとえば、新しいワーカーが待機をスキップして、新しいアクティブなワーカーになったとします。

navigator.serviceWorker.addEventListener("controllerchange", event => {
   // The service worker controller has changed
 });

メタデータの更新

アプリのメタデータを更新することもできます。メタデータは主にウェブアプリ マニフェストで設定します。たとえば、アイコン、名前、開始 URL を更新したり、アプリのショートカットなどの新機能を追加したりできます。 しかし、古いアイコンが付いたアプリをすでにデバイスにインストールしているすべてのユーザーはどうなりますか?アップデートはいつ、どのように提供されますか?

答えはプラットフォームによって異なります。利用可能なオプションを見てみましょう

iOS、iPadOS、Android ブラウザ上の Safari

これらのプラットフォームで新しいマニフェスト メタデータを取得する唯一の方法は、ブラウザからアプリを再インストールすることです。

WebAPK を使用する Android 版 Google Chrome

ユーザーが WebAPK を有効にした Google Chrome を使用して Android に PWA をインストールすると(ほとんどの Chrome PWA インストール)、アルゴリズムに基づいて更新が検出され、適用されます。詳しくは、マニフェストの更新に関する記事をご覧ください。

このプロセスに関するその他の注意事項:

ユーザーが PWA を開かなかった場合、WebAPK は更新されません。サーバーからマニフェスト ファイルによる応答がない場合(404 エラーが発生している場合)は、ユーザーが PWA を開いても、最低 30 日間は更新の確認が行われません。

Android 版 Chrome で about:webapks にアクセスして「更新が必要」フラグのステータスを確認し、更新をリクエストしてください。このデバッグツールの詳細については、ツールとデバッグの章をご覧ください。

WebAPK を使用した Android での Samsung Internet

手順は Chrome の場合と同様です。この場合、PWA マニフェストの更新が必要な場合は、更新された WebAPK の作成後、24 時間以内に Wi-Fi 上で WebAPK が更新されます。

パソコンの Google Chrome と Microsoft Edge

デスクトップ デバイスでは、PWA が起動されると、ブラウザが最後にローカル マニフェストの変更を確認した時間を特定します。マニフェストがブラウザが最後に起動してから確認されていない場合や、過去 24 時間以内にマニフェストが確認されていない場合、ブラウザはマニフェストのネットワーク リクエストを行い、ローカルコピーと比較します。

選択されたプロパティが更新されると、すべてのウィンドウが閉じられた後に更新がトリガーされます。

ユーザーへのアラート

一部の更新戦略では、クライアントからの再読み込みまたは新しいナビゲーションが必要になります。ユーザーにアップデートが待っていることを知らせ、適切なタイミングでページを更新する機会を提供します。

ユーザーに通知するには、次の方法があります。

  • DOM または canvas API を使用して、画面に通知をレンダリングします。
  • Web Notifications API を使用する。この API は、オペレーティング システムで通知を生成する push 権限の一部です。お使いのサーバーでプッシュ メッセージング プロトコルを使用していない場合でも、使用するにはウェブ push 権限をリクエストする必要があります。PWA が開いていない場合、これが唯一の選択肢です。
  • Badging API を使用して、PWA のインストール済みアイコンで更新が利用できることを示します。

DOM に表示された更新通知。.

Badging API の詳細

Badging API を使用すると、PWA のアイコンにバッジ番号または対応ブラウザの場合はバッジドットをマークできます。バッジのドットは、インストール済みのアイコン内にある小さなマークで、アプリ内で何かが待機中であることを示します。

8 件の通知が表示された Twitter と、旗タイプのバッジを表示しているもう 1 つのアプリの例。

バッジ番号を設定するには、navigator オブジェクトの setAppBadge(count) を呼び出す必要があります。これは、ユーザーに警告する更新があることがわかっているときに、ウィンドウまたは Service Worker のコンテキストから行うことができます。

let unreadCount = 125;
navigator.setAppBadge(unreadCount);

バッジをクリアするには、同じオブジェクトの clearAppBadge() を呼び出します。

navigator.clearAppBadge();

リソース