ZDF がオフライン サポート、インストール、ダークモードなどの最新機能を備えたプログレッシブ ウェブアプリ(PWA)を作成した方法を学びます。
放送局の ZDF は、フロントエンド テクノロジー スタックの再設計を検討していたときに、ストリーミング サイト ZDFmediathek のプログレッシブ ウェブアプリを詳しく調べることにしました。開発会社 Cellular は、ZDF のプラットフォーム固有の iOS アプリと Android アプリに匹敵するウェブベースのエクスペリエンスを構築するという課題に取り組みました。この PWA には、インストール性、オフライン動画再生、遷移アニメーション、ダークモードが用意されています。
Service Worker の追加
PWA の主な機能はオフライン サポートです。ZDF では、ほとんどの負荷は Workbox によって処理されます。これは、さまざまなキャッシュ戦略を簡単にサポートできる一連のライブラリと Node モジュールです。ZDF PWA は TypeScript と React で構築されているため、create-react-app に組み込まれている Workbox ライブラリを使用して静的アセットをプリキャッシュします。これにより、アプリケーションは動的コンテンツ(この場合は動画とそのメタデータ)をオフラインで利用できるようにすることに集中できます。
基本的な考え方は非常にシンプルです。動画を取得して、IndexedDB に blob として保存します。次に、再生中にオンライン / オフライン イベントをリッスンし、デバイスがオフラインになったときにダウンロード済みバージョンに切り替えます。
残念ながら、状況は少し複雑でした。プロジェクトの要件の 1 つは、オフライン サポートを提供しない公式の ZDF ウェブ プレーヤーを使用することです。プレーヤーは Content ID を入力として受け取り、ZDF API と通信して、関連する動画を再生します。
そこで役に立つのが、ウェブの最も強力な機能の一つである Service Worker です。
Service Worker は、プレーヤーが行ったさまざまなリクエストをインターセプトし、IndexedDB のデータでレスポンスを返すことができます。これにより、プレーヤーのコードを一行も変更することなく、オフライン機能を透過的に追加できます。
オフライン動画は非常にサイズが大きくなるため、デバイスに実際に保存できる動画の数は大きな問題です。アプリは StorageManager API を使用して、使用可能な容量を推定し、ダウンロードを開始する前に空き容量が不足していることをユーザーに通知できます。残念ながら、Safari はこの API を実装しているブラウザのリストに含まれていません。また、執筆時点では、他のブラウザが割り当てを適用する方法に関する最新情報はあまりありませんでした。そのため、チームはさまざまなデバイスでの動作をテストするために小さなユーティリティを作成しました。すべての詳細をまとめた包括的な記事が公開されています。
カスタムのインストール プロンプトを追加する
ZDF PWA はカスタムのアプリ内インストール フローを備えており、ユーザーが最初の動画をダウンロードしようとするとすぐにアプリをインストールするよう求めるメッセージを表示します。これは、ユーザーがアプリをオフラインで使用する明確な意図を示しているため、インストールを促す良いタイミングです。
ダウンロードにアクセスするためのオフライン ページを作成する
デバイスがインターネットに接続されておらず、ユーザーがオフライン モードで利用できないページに移動すると、代わりに特別なページが表示されます。このページには、以前にダウンロードされたすべての動画がリストされます(コンテンツがまだダウンロードされていない場合は、オフライン機能の簡単な説明が表示されます)。
アダプティブ機能にフレーム読み込みレートを使用する
豊かなユーザー エクスペリエンスを提供するために、ZDF PWA には、ユーザーがスクロールまたはナビゲートするときに発生する微妙な遷移が含まれています。ローエンド デバイスでは、このようなアニメーションは通常逆効果をもたらし、60 フレーム/秒で実行しないとアプリの動作が遅く、応答性が低下します。これを考慮して、アプリはアプリケーションの読み込み中に requestAnimationFrame()
を介して実際のフレームレートを測定し、値が特定のしきい値を下回るとすべてのアニメーションを無効にします。
const frameRate = new Promise(resolve => {
let lastTick;
const samples = [];
function measure() {
const tick = Date.now();
if (lastTick) samples.push(tick - lastTick);
lastTick = tick;
if (samples.length < 20) requestAnimationFrame(measure);
else {
const avg = samples.reduce((a, b) => a + b) / samples.length;
const fps = 1000 / avg;
resolve(fps);
}
}
measure();
});
この測定はデバイスのパフォーマンスの概要しか提供せず、負荷ごとに変動する場合でも、意思決定の基礎として十分に役立ちました。ユースケースに応じて、デベロッパーが実装できる適応型読み込みの他の手法もあります。このアプローチの大きな利点の 1 つは、すべてのプラットフォームで使用できることです。
ダークモード
最新のモバイル エクスペリエンスで人気のある機能は、ダークモードです。特に周囲が暗い場所で動画を視聴する場合、多くのユーザーは UI を暗くすることを好みます。ZDF PWA には、ユーザーがライトモードとダークモードを切り替えることができるスイッチが用意されているだけでなく、OS 全体の色設定の変更にも対応しています。これにより、時間帯に基づいてテーマを変更するスケジュールを設定しているデバイスでは、アプリの外観が自動的に変更されます。
結果
新しいプログレッシブ ウェブアプリは、2020 年 3 月に公開ベータ版としてリリースされ、それ以来多くの肯定的なフィードバックをいただいています。ベータ版の段階では、PWA は引き続き独自の一時ドメインで実行されます。PWA は一般公開されていませんが、ユーザー数は着実に増加しています。これらの多くは Microsoft Store から入手できます。Windows 10 ユーザーは、PWA を見つけて、プラットフォーム固有のアプリのようにインストールできます。
次のステップ
ZDF は、パーソナライズのためのログイン、クロスデバイスおよびプラットフォームの表示、プッシュ通知などの機能を PWA に引き続き追加していく予定です。