マルチオリジン サイトでのプログレッシブ ウェブアプリ

マルチオリジン サイトでプログレッシブ ウェブアプリを構築する際の課題と回避策を紹介します。

Demián Renzulli 氏
Demián Renzulli 氏

背景

これまでは、マルチオリジン アーキテクチャを使用する利点もいくつかありましたが、プログレッシブ ウェブアプリの場合、このアプローチには多くの課題が伴います。特に、同一オリジン ポリシーにより、Service Worker やキャッシュ、権限などの共有や、複数のオリジンでのスタンドアロン エクスペリエンスの実現などに関する制限が課されます。この記事では、複数のオリジンの良い点と悪い使い方、そしてマルチオリジン サイトでプログレッシブ ウェブアプリを構築する際の課題と回避策について説明します。

複数のオリジンの良い点と悪い点

サイトがマルチオリジン アーキテクチャを採用することには、いくつかの正当な理由があります。そのほとんどは、独立したウェブ アプリケーション セットの提供や、互いに完全に分離されたエクスペリエンスの作成に関連しています。避けるべき使用方法もあります。

メリット

まず、有用な理由を見てみましょう。

  • ローカライズ / 言語: 国コード トップレベル ドメインを使用して、異なる国で提供するサイトを分ける(例: https://www.google.com.ar)、異なる地域をターゲットとするサイトをサブドメインで分割する(例:https://newyork.craigslist.org)を指定したり、特定の言語(https://en.wikipedia.org など)のコンテンツを提供したりできます。

  • 独立したウェブアプリ: 異なるサブドメインを使用して、メインのオリジンのサイトとは目的がかなり異なるユーザー エクスペリエンスを提供している。たとえば、ニュースサイトの場合、メインのウェブサイトとリソースや機能を共有しなくても、クロスワード ウェブアプリを https://crosswords.example.com から意図的に配信し、独立した PWA としてインストールして使用できます。

悪い例

これらのことをいずれも行っていない場合、プログレッシブ ウェブアプリを構築する際に、マルチオリジン アーキテクチャの使用は不利になる可能性があります。

それにもかかわらず、特定の理由や「レガシー」の理由から、多くのサイトはこのような構造を続けています。その一例として、サブドメインを使用して、統一されたエクスペリエンスの一部となるべきサイトの各部分を任意に分離することが挙げられます。

たとえば、次のようなパターンはおすすめしません。

  • サイトのセクション: サイトの複数のセクションをサブドメインで区切ること。ニュースサイトの場合、ホームページが https://www.example.com、スポーツ セクションが https://sports.example.com、政治ニュースが https://politics.example.com などに表示されることがあります。e コマースサイトの場合、商品カテゴリには https://category.example.com、商品ページには https://product.example.com などを使用します。

  • ユーザーフロー: もう一つ、推奨されないアプローチとして、サブドメインのログインフローや購入フローのページなど、サイトの小さな部分を分けるというアプローチがあります。たとえば、https://login.example.comhttps://checkout.example.com を使用します。

単一のオリジンへの移行が不可能な場合の課題と、可能な場合にはプログレッシブ ウェブアプリの構築時に検討できる回避策を以下にまとめます。

オリジンが異なる PWA の課題と回避策

複数のオリジンでウェブサイトを構築する場合、統一された PWA エクスペリエンスを提供することは困難です。その主な原因は、多くの制約が課される同一オリジン ポリシーが原因です。1 つずつ見ていきましょう。

Service Worker

Service Worker スクリプトの URL の生成元は、register() を呼び出すページの生成元と同じである必要があります。つまり、https://www.example.com のページは https://section.example.com の Service Worker URL で register() を呼び出すことはできません。

もう 1 つの考慮事項は、Service Worker が制御できるのは、そのオリジンとパスが属しているページのみであることです。つまり、Service Worker が https://www.example.com でホストされている場合、Service Worker は(scope パラメータで定義されたパスに従って)そのオリジンからの URL のみを制御でき、他のサブドメインのページ(https://section.example.com のページなど)を制御することはできません。

この場合、唯一の回避策は複数の Service Worker を使用することです(オリジンごとに 1 つ)。

キャッシュ

Cache オブジェクト、indexedDB、localStorage も、単一のオリジンに制約されています。つまり、https://www.example.com に属するキャッシュには https://www.section.example.com などからアクセスできません。

次のような場合に、キャッシュを適切に管理するためにできることをいくつか紹介します。

  • ブラウザ キャッシュを活用する: 従来のブラウザ キャッシュのベスト プラクティスを実践することをおすすめします。この方法には、Service Worker のキャッシュではできない、キャッシュに保存されたリソースをオリジン間で再利用できるという利点があります。Service Worker で HTTP Cache を使用する方法のベスト プラクティスについては、こちらの投稿をご覧ください。

  • Service Worker のインストールを軽量化する: 複数の Service Worker を維持する場合、ユーザーが新しいオリジンに移動するたびに多額のインストール コストを支払うことは避けます。つまり、絶対に必要なリソースのみをプリキャッシュします。

権限

権限のスコープもオリジンです。つまり、ユーザーがオリジンの https://section.example.com に特定の権限を付与しても、その権限が他のオリジン(https://www.example.com など)に引き継がれることはありません。

オリジン間で権限を共有する方法はないため、ここでの唯一の解決策は、特定の機能(位置情報など)が必要な各サブドメインで権限をリクエストすることです。ウェブプッシュなどでは、別のサブドメインでユーザーが権限を許可したかどうかを追跡する Cookie を保持して、再度リクエストするのを防ぐことができます。

インストール

PWA をインストールするには、各オリジンに独自のマニフェスト(start_url自身に対する相対関係)を持つ必要があります。つまり、特定のオリジン(https://section.example.com)でインストール プロンプトを受け取ったユーザーは、start_url で別のオリジン(https://www.example.com)で PWA をインストールできません。つまり、サブドメインでインストール プロンプトを受け取ったユーザーは、アプリのメイン URL ではなく、サブページにのみ PWA をインストールできます。

また、各サブドメインがインストール条件を満たし、ユーザーに PWA のインストールを求めた場合、同じユーザーがサイトを移動するとインストール プロンプトが複数表示されるという問題もあります。

この問題を軽減するには、プロンプトがメインのオリジンにのみ表示されるようにします。インストール条件を満たすサブドメインにユーザーがアクセスした場合:

  1. beforeinstallprompt イベントをリッスンする
  2. メッセージが表示されないようにして、event.preventDefault() を呼び出します。

これにより、メインのオリジン(ホームページなど)など、サイトの意図しない部分にはメッセージを表示し続けることができます。

スタンドアロン モード

スタンドアロン ウィンドウで操作しているときに、ユーザーが PWA のマニフェストで設定されたスコープ外に移動すると、ブラウザの動作は変わります。動作はブラウザのバージョンやベンダーによって異なります。たとえば、最新バージョンの Chrome では、ユーザーがスタンドアロン モードでサポート範囲外に移動すると、Chrome カスタムタブが開きます。

ほとんどの場合、これに対する解決策はありませんが、サブドメインでホストされているエクスペリエンスの一部(ログイン ワークフローなど)に回避策を適用できます。

  1. 新しい URL https://login.example.com は全画面表示の iframe 内で開くことができます。
  2. iframe 内でタスク(ログイン プロセスなど)が完了したら、postMessage() を使用して、結果の情報を iframe から親ページに戻すことができます。
  3. 最後のステップとして、メッセージがメインページで受信されたら、リスナーの登録を解除し、最終的に iframe を DOM から削除します。

まとめ

同一オリジン ポリシーは、一貫した PWA エクスペリエンスを実現したい、複数のオリジンに基づいて構築されているサイトに対して多くの制限を課すものです。そのため、優れたユーザー エクスペリエンスを提供するため、サイトを複数のオリジンに分けることはおすすめしません。

すでにこの方法で構築されている既存のサイトの場合、マルチオリジン PWA を正しく動作させるのは難しい場合がありますが、考えられる回避策をいくつか確認しました。それぞれにトレードオフが伴うため、ウェブサイトでどのアプローチを採用するかは慎重に判断してください。

長期的な戦略やサイトの再設計を評価するときは、マルチオリジン アーキテクチャを維持すべき重要な理由がない限り、単一のオリジンへの移行を検討してください。

Penny Mclachlan、Paul Covell、Dominick Ng、Alberto Medina、Pete LePage、Joe Medley、Cheney Tsai、Martin Schierle、Andre Bandarra の技術的なレビューと提案に感謝します。