PWA をアプリのような感覚にさせる

プログレッシブ ウェブアプリを、ウェブサイトではなく「本物」のアプリのように感じさせる

プログレッシブ ウェブアプリの流行語ビンゴをプレイするときは、「PWA は単なるウェブサイトである」と安心できる。Microsoft の PWA に関するドキュメントは同意しており、このサイトでも説明しています。また、PWA のノミネータである Frances Berriman と Alex Russell もそのように書いています。はい。PWA は単なるウェブサイトですが、それだけではありません。うまくいけば、PWA はウェブサイトではなく「本物」のアプリのように感じられます。では、本物のアプリのように感じられるとはどういう意味でしょうか。

この質問に答えるために、Apple Podcasts アプリを例に考えてみましょう。パソコンの macOS とモバイルの iOS(および iPadOS)で利用できます。Podcasts はメディア アプリケーションですが、ここで紹介した基本的な考え方は他のカテゴリのアプリにも当てはまります。

Podcasts アプリを実行している iPhone と MacBook。
iPhone および macOS の Apple Podcasts(出典)。

オフラインでの実行可能

一歩引いて、スマートフォンやデスクトップ パソコンに搭載されているプラットフォーム固有のアプリケーションを考えてみると、明らかに目立つ点が 1 つあります。それは、何も取得されないということです。Podcasts アプリでは、オフラインの場合でも常に何かが表示されます。ネットワークに接続されていなくても、アプリは自然に開きます。[ランキング] セクションにはコンテンツが表示されず、[現在接続できません] のメッセージに [再試行] ボタンが表示されます。あまり快適ではないかもしれませんが、ある程度満足しています。

ネットワークに接続できないときに、Podcasts アプリに「現在接続できません」という情報メッセージが表示される。
ネットワーク接続のないポッドキャスト アプリ。

Podcasts アプリは、いわゆる App Shell モデルを採用しています。左側のメニュー アイコンやコア プレーヤー UI アイコンなどの装飾画像を含め、コアアプリを表示するために必要なすべての静的コンテンツがローカルのキャッシュに保存されます。ランキング データなどの動的コンテンツはオンデマンドでのみ読み込まれます。読み込みが失敗した場合は、ローカルのキャッシュに保存された代替コンテンツを利用できます。このアーキテクチャ モデルをウェブアプリに適用する方法については、App Shell モデルの記事をご覧ください。

オフライン コンテンツを利用可能、メディアを再生可能

オフラインのときも、左側のドロワーから [Downloaded] セクションに移動できます。ダウンロードしたポッドキャストのエピソードはすぐに再生でき、アートワークや説明などのすべてのメタデータとともに表示されます。

ポッドキャストのダウンロード エピソードが再生されているポッドキャスト アプリ。
ダウンロードしたポッドキャストのエピソードは、ネットワークがなくても再生できます。

以前にダウンロードしたメディア コンテンツは、Workbox ライブラリのキャッシュに保存された音声と動画を提供するレシピを使用して、キャッシュから配信できます。その他のコンテンツは常にキャッシュまたは IndexedDB に保存できます。詳細と、どのストレージ テクノロジーをどのような場合に使用するかについては、ウェブ用のストレージの記事をご覧ください。使用可能なメモリ量が少なくなったときにパージされるリスクなしに、永続的に保存する必要があるデータがある場合は、Persistent Storage API を使用できます。

バックグラウンドでのプロアクティブなダウンロード

オンラインに戻ったら、もちろん「http 203」のようなクエリでコンテンツを検索できます。検索結果に登録すると、質問なしで HTTP 203 ポッドキャストというシリーズの最新エピソードがすぐにダウンロードされます。

登録後すぐにポッドキャストの最新エピソードをダウンロードする Podcasts アプリ。
ポッドキャストに登録すると、最新のエピソードが直ちに一時保存されます。

ポッドキャスト エピソードのダウンロードは、処理に時間がかかる可能性があります。Background Fetch API を使用すると、ダウンロードをブラウザに委任できます。ブラウザはバックグラウンドでダウンロードを処理します。Android では、ブラウザがダウンロードをオペレーティング システムに委任することもできるため、ブラウザを継続的に実行する必要はありません。ダウンロードが完了すると、アプリの Service Worker が起動し、レスポンスの処理方法を決定できます。

他のアプリと共有、他のアプリとやり取りする

Podcasts アプリは他のアプリと自然に統合されます。たとえば、気に入ったエピソードを右クリックすると、デバイス上のメッセージ アプリなどの他のアプリと共有できます。また、システム クリップボードにも自然に組み込まれます。エピソードを右クリックして、リンクをコピーできます。

[エピソードを共有] > [メッセージ] オプションが選択されたポッドキャスト エピソードで呼び出される、Podcasts アプリのコンテキスト メニュー。
メッセージ アプリでポッドキャストのエピソードを共有する。

Web Share APIWeb Share Target API を使用すると、デバイス上の他のアプリとの間でテキスト、ファイル、リンクを共有および受信できます。ウェブアプリでオペレーティング システムに組み込まれた右クリック メニューにメニュー項目を追加することはできませんが、デバイス上の他のアプリとの間でリンクする方法は他にもたくさんあります。Async Clipboard API を使用すると、テキストと画像データ(PNG 画像)をプログラムでシステム クリップボードに書き込むことができます。Android では、Contact Picker API を使用して、デバイスの連絡先マネージャーからエントリを選択できます。プラットフォーム固有のアプリと PWA の両方を提供する場合は、Get Installed Related Apps API を使用して、プラットフォーム固有のアプリがインストールされているかどうかを確認できます。この場合、ユーザーに PWA のインストールを促したり、ウェブプッシュ通知を受け入れたりする必要はありません。

アプリのバックグラウンド更新

ポッドキャスト アプリの設定で、新しいエピソードを自動的にダウンロードするようアプリを設定できます。そのようなことを考える必要すらありません。更新されたコンテンツが常にそこにあります。魔法です。

Podcasts アプリの設定メニューの [全般] セクションにある、[ポッドキャストの更新] オプションが [1 時間ごと] に設定されている。
1 時間ごとに新しいポッドキャスト エピソードを確認するように構成されているポッドキャスト。

Periodic Background Sync API を使用すると、アプリを実行しなくても、バックグラウンドでコンテンツを定期的に更新できます。つまり、新しいコンテンツが事前に利用可能になるため、ユーザーは決断したらすぐに詳しく調べることができます。

クラウド経由で状態を同期

それと同時に、所有するすべてのデバイスで定期購入が同期されます。シームレスな世界では、ポッドキャストの登録チャンネルを手動で同期させる必要がありません。同様に、モバイル デバイスのメモリが、パソコンですでに視聴したエピソードによって消費されることを心配する必要はありません。再生状態は同期され、再生したエピソードは自動的に削除されます。

Podcasts アプリの設定メニューの [詳細設定] セクションで [サブスクリプションをデバイス間で同期] オプションが有効になっている。
状態はクラウドを介して同期されます。

アプリの状態データの同期は、Background Sync API に委任できるタスクです。同期処理自体はすぐに行う必要はなく、最終的にのみ行う必要があり、ユーザーがすでにアプリを再度閉じたときに行う場合もあります。

ハードウェア メディア キー コントロール

たとえば、Chrome ブラウザでニュースページを閲覧しているときなど、別のアプリケーションで忙しいときでも、ノートパソコンのメディアキーで Podcasts アプリを操作できます。 早送りや巻き戻しのためにアプリに切り替える必要はありません。

注釈付きのメディアキーを備えた Apple MacBook Pro Magic Keyboard。
メディアキーを使用して、ポッドキャスト アプリ(ソース)を操作できます。

メディアキーは Media Session API でサポートされています。ユーザーは、物理キーボードやヘッドフォンのハードウェア メディアキーを使用したり、スマートウォッチのソフトウェア メディアキーからウェブアプリを操作したりできます。シーク操作をスムーズにするためのもう 1 つの方法として、開始クレジットや章の境界を渡すなど、ユーザーがコンテンツの大部分をシークしたときにバイブレーション パターンを送信することもできます。

マルチタスクとアプリのショートカット

もちろん、いつでもどこからでもポッドキャスト アプリにマルチタスクを実行できます。アプリのアイコンがはっきりわかるので、デスクトップやアプリケーション ドックに配置すれば、気軽にポッドキャストをすぐに開始できます。

いくつかのアプリアイコン(そのうちの 1 つは Podcasts アプリ)がある macOS タスク スイッチャー。
Podcasts アプリにマルチタスクで戻る。

プログレッシブ ウェブアプリは、パソコンとモバイルのどちらからでも、ホーム画面、スタート メニュー、アプリケーション ドックにインストールできます。 インストールは、プロアクティブなプロンプトに基づいて行うことも、アプリ デベロッパーが完全に制御することもできます。知っておくべきポイントはすべて、インストール可能にするための要件の記事に記載されています。 マルチタスクの場合、PWA はブラウザから独立しているように見えます。

コンテキスト メニューでのクイック操作

アプリでよく使う操作である新しいコンテンツの [検索] や [新しいエピソードの確認] には、Dock のアプリのコンテキスト メニューからアクセスできます。[オプション] メニューから、ログイン時にアプリを開くこともできます。

[検索] オプションと [新しいエピソードを確認] オプションが表示された Podcasts アプリのアイコンのコンテキスト メニュー。
クイック操作は、アプリアイコンからすぐに利用できます。

PWA のウェブアプリ マニフェストでアプリアイコンのショートカットを指定すると、ユーザーがアプリアイコンから直接アクセスできる一般的なタスクへのクイックルートを登録できます。macOS などのオペレーティング システムでは、ユーザーがアプリアイコンを右クリックして、ログイン時にアプリが起動するように設定することもできます。ログイン時に実行の提案に関する作業が進行中です。

デフォルト アプリとして動作

podcasts:// URL スキームを利用することで、他の iOS アプリやウェブサイトやメールもポッドキャスト アプリと統合できます。ブラウザで podcasts://podcasts.apple.com/podcast/the-css-podcast/id1042283903 などのリンクをクリックすると、Podcasts アプリがすぐに開き、ポッドキャストの登録や再生を選択できます。

Podcasts アプリを開くかどうかをユーザーに尋ねる確認ダイアログが表示されている Chrome ブラウザ。
ポッドキャスト アプリはブラウザから直接開くことができます。

完全なカスタム URL スキームの処理はまだ不可能ですが、PWA 向けの URL プロトコル処理の提案に向けて取り組みが進行中です。現時点では、web+ スキーム接頭辞を持つ registerProtocolHandler() が最適な代替手段です。

ローカル ファイル システムの統合

そのように思われるかもしれませんが、Podcasts アプリはローカル ファイル システムと自然に統合されています。ポッドキャストのエピソードをダウンロードすると、ノートパソコンでは ~/Library/Group Containers/243LU875E5.groups.com.apple.podcasts/Library/Cache に保存されています。たとえば、~/Documents とは異なり、このディレクトリは通常のユーザーが直接アクセスするためのものではありませんが、存在します。ファイル以外のストレージ メカニズムについては、オフライン コンテンツのセクションで説明しています。

macOS Finder で Podcasts アプリのシステム ディレクトリに移動します。
ポッドキャストのエピソードは、特別なシステムアプリフォルダに保存されます。

デベロッパーは File System Access API を使用して、デバイスのローカル ファイル システムにアクセスできます。直接使用することも、API をサポートしていないブラウザに対して透過的にフォールバックを提供する browser-fs-access サポート ライブラリを介して使用することもできます。セキュリティ上の理由から、システム ディレクトリはウェブアクセスできません。

プラットフォームのデザイン

Podcasts のような iOS アプリでは、もっと明白なことがあります。どのテキストラベルも選択できず、すべてのテキストがパソコンのシステム フォントに溶け込んで表示されます。また、選択したシステムカラーテーマ(ダークモード)も尊重されます。

ダークモードの Podcasts アプリ。
ポッドキャスト アプリはライトモードとダークモードをサポートしています。
ライトモードの Podcasts アプリ。
アプリはデフォルトのシステム フォントを使用します。

none の値を指定して user-select CSS プロパティを利用すると、UI 要素が誤って選択されないように保護できます。ただし、このプロパティを悪用してアプリのコンテンツを選択不能にすることは避けてください。ボタンのテキストなどの UI 要素にのみ使用してください。font-family CSS プロパティの system-ui 値を使用すると、アプリに使用するシステムのデフォルト UI フォントを指定できます。アプリは、ユーザーの prefers-color-scheme 選択を尊重し、オプションのダークモードの切り替えでオーバーライドできます。もう 1 つの決定すべきことは、たとえば、カスタムの「プルして更新」を実装する場合など、スクロール領域の境界に達したときのブラウザの動作です。これは、CSS プロパティ overscroll-behavior で行うことができます。

カスタマイズされたタイトルバー

Podcasts アプリのウィンドウを見ると、Safari ブラウザ ウィンドウなど従来の統合されたタイトルバーとツールバーはなく、メインのプレーヤー ウィンドウにドッキングされたサイドバーのようにカスタマイズされたエクスペリエンスであることがわかります。

Safari ブラウザに組み込まれたタイルバーとツールバー。
Podcasts アプリのカスタマイズされた分割でカスタマイズされたタイトルバー。
Safari とポッドキャストのタイトルバーのカスタマイズ

現時点ではできませんが、現在、タイトルバーのカスタマイズに取り組んでいます。ただし、ウェブアプリ マニフェストの display プロパティと theme-color プロパティを指定することで、アプリ ウィンドウのデザインを決定し、どのデフォルトのブラウザ コントロールを表示しないかを決定できます。

テンポの良いアニメーション

ポッドキャストのアプリ内アニメーションはテンポよく滑らかです。たとえば、右側の [エピソードのメモ] ドロワーを開くと、見やすくスライドして表示します。一時保存したエピソードから 1 つのエピソードを削除すると、残りのエピソードがフローティングして、削除したエピソードによって解放された画面領域を消費します。

[エピソードのメモ] ドロワーが展開された Podcasts アプリ。
ドロワーを開くときなどのアプリ内アニメーションがテンポよく表示される。

アニメーションとパフォーマンスの記事で説明されているさまざまなベスト プラクティスを検討すれば、ウェブで高パフォーマンスのアニメーションを実現できます。ページ分けされたコンテンツやメディア カルーセルで一般的に見られるスクロール アニメーションは、CSS のスクロール スナップ機能を使用すると、大幅に改善できます。完全に制御するには、Web Animations API を使用します。

コンテンツがアプリ外に表示される

iOS の Podcasts アプリは、実際のアプリ以外の場所にコンテンツを表示できます。たとえば、システムのウィジェット ビューに、Siri の候補の形式でコンテンツを表示できます。タップ 1 回で反応できる、利用状況に基づいた積極的な行動を促すフレーズを使用すると、ポッドキャストのようなアプリの再エンゲージメント率を大幅に高めることができます。

ポッドキャストの新しいエピソードをおすすめする Podcasts アプリが表示されている iOS ウィジェット ビュー。
アプリのコンテンツがメインのポッドキャスト アプリ外に表示されている。

Content Index API を使用すると、アプリはオフラインで使用できる PWA のコンテンツをブラウザに伝えることができます。これにより、ブラウザはメインアプリの外部にこのコンテンツを表示できるようになります。アプリ内の興味深いコンテンツを音声再生に適したものとしてマークアップし、構造化マークアップ全般を使用することで、検索エンジンや Google アシスタントなどの仮想アシスタントが、理想的な形でサービスを提示できるようになります。

ロック画面のメディア コントロール ウィジェット

ポッドキャスト エピソードの再生中は、Podcasts アプリのロック画面に美しいコントロール ウィジェットが表示されます。このウィジェットには、エピソードのアートワーク、エピソードのタイトル、ポッドキャスト名などのメタデータが表示されます。

ロック画面に iOS のメディア再生ウィジェットで、リッチ メタデータを含むポッドキャスト エピソードが表示されている。
アプリで再生中のメディアをロック画面から操作できる。

Media Session API を使用すると、アートワークやトラックのタイトルなどのメタデータを指定できます。指定したメタデータは、ブラウザのロック画面、スマートウォッチ、その他のメディア ウィジェットに表示されます。

プッシュ通知

プッシュ通知は、ウェブ上ではやや煩わしさが増しました(通知プロンプトの表示はかなり静かになりました)。しかし、適切に活用すれば、多くの価値を付加できます。たとえば、iOS Podcasts アプリでは、登録しているポッドキャストの新しいエピソードの通知や新しいエピソードのおすすめ、アプリの新機能に関する通知を任意で受け取ることができます。

[通知] 設定画面の iOS Podcasts アプリ。[新エピソード] 通知の切り替えが有効になっています。
アプリからユーザーに新しいコンテンツを知らせるプッシュ通知を送信できます。

Push API を使用すると、アプリでプッシュ通知を受信して、PWA に関する重要なイベントについてユーザーに通知できます。将来の既知の時刻に呼び出される通知で、ネットワーク接続を必要としない場合は、Notification Triggers API を使用できます。

アプリアイコンのバッジ

登録しているポッドキャストで新しいエピソードが利用できるようになると、Podcasts のホーム画面アイコンにアプリアイコン バッジが表示され、邪魔にならない方法でアプリの利用を再開してくれます。

[バッジ] 切り替えボタンが有効になっている iOS 設定画面。
バッジは、新しいコンテンツをアプリがユーザーに知らせるための控えめな手段です。

Badging API を使用して、アプリアイコンのバッジを設定できます。これは、PWA に「未読」の概念がある場合や、ユーザーの注意をアプリに呼び戻す手段が必要な場合に特に役立ちます。

メディアの再生は省エネ設定よりも優先されます

ポッドキャスト メディアの再生中は、画面がオフになることがありますが、システムはスタンバイ モードになりません。 アプリでは、歌詞や字幕を表示するなど、必要に応じて画面をスリープ解除することもできます。

macOS の [省エネモード] の設定
アプリは画面を ON にすることができます。

Screen Wake Lock API を使用すると、画面がオフになるのを防ぐことができます。ウェブ上でのメディア再生により、システムがスタンバイ モードに入ることを自動的に阻止します。

アプリストアでアプリを見つける

Podcasts アプリは macOS のデスクトップ エクスペリエンスの一部ですが、iOS では App Store からインストールする必要があります。podcastpodcastsapple podcasts をクイック検索すると、すぐに App Store のアプリが表示されます。

iOS App Store で「podcasts」を検索すると、Podcasts アプリが表示されます。
ユーザーはアプリストアでアプリを見つける方法を学びました。

Apple は App Store での PWA を許可していませんが、Android では、信頼できるウェブ アクティビティでラップされた PWA を送信できます。これは、bubblewrap スクリプトで簡単に行えます。このスクリプトは、PWABuilder の Android アプリのエクスポート機能を内部的に使用するためにも使用されています。この機能は、コマンドラインに触れることなく使用できます。

機能の概要

以下の表に、すべての機能を簡潔にまとめた概要と、それらをウェブで実現する際に役立つリソースのリストを示します。

特徴 ウェブでこれを行うのに役立つリソース
オフラインで実行できる
オフライン コンテンツと再生可能なメディア
プロアクティブなバックグラウンドでのダウンロード
他のアプリと共有および操作
アプリのバックグラウンド更新
状態がクラウド経由で同期
ハードウェア メディア キー コントロール
マルチタスクとアプリのショートカット
コンテキスト メニューでのクイック操作
デフォルト アプリとして設定する
ローカル ファイル システムの統合
プラットフォームのデザイン
タイトルバーのカスタマイズ
テンポの良いアニメーション
アプリの外に表示されるコンテンツ
ロック画面のメディア コントロール ウィジェット
プッシュ通知
アプリアイコンのバッジ
メディアの再生が省エネ設定よりも優先される
アプリストアでアプリを見つける

おわりに

PWA は、2015 年に導入されて以来、大きな進化を遂げました。プロジェクト Fugu 🐡? において、会社をまたぐ Chromium チームは、残りわずかなギャップの解消に取り組んでいます。 この記事で紹介しているアドバイスを少しでも実践するだけで、アプリのような感覚に少しずつ近づき、ユーザーは「ウェブサイトだけ」にしか対処していないことを忘れさせることができます。正直なところ、ユーザーのほとんどは、実際のアプリのように感じられるのであれば、アプリがどのように構築され、なぜそうすべきかは気にしていないからです。

謝辞

この記事は、 Kayce BasquesJoe MedleyJoshua BellDion AlmaerAde OshineyePete LePageSam ThorogoodReilly Grantand、Reilly Grantand によってレビューされました。