概要
「サンタ トラッカー」は、既存のシーンデザインも一部改善されており、2016 年のホリデー シーズンに向けて、オフラインのプログレッシブ ウェブアプリに急速にアップグレードされました。
結果
- サンタは、ホーム画面への追加(ATHS)とオフラインをサポートするプログレッシブ ウェブアプリ(PWA)です
- 対象セッションの 10% が ATHS アイコンから開始
- 75% のユーザーが、ウェブ コンポーネントの 2 つの主要部分であるカスタム要素と Shadow DOM をネイティブにサポートしました。
- Lighthouse のスコア: 81
- オフラインは Service Worker API を通じて遅延読み込みと紐付けられ、訪問されたシーンのみがキャッシュされ、新しいリリースでは通知なくアップグレードされる
背景
サンタ トラッカーは Google におけるホリデー シーズンの定番機能です。毎年 12 月は、ゲームや学習体験でホリデー シーズンを満喫できます。サンタさんには十分な一休みが必要ですが、エルフはサンタを追いかけようをウェブと Android の両方でオープンソースとしてリリースしようとしています。
ウェブ上の「サンタを追いかけよう」は、Polymer を使用して記述された多くのユニークな「シーン」を持つ、大規模でインタラクティブなサイトであり、最新のブラウザに対応しています。ユーザーのブラウザが「最新」かどうかの評価は、機能検出によって決定されます。サンタには、特に Set
と Web Performance API が必要です。
2016 年、Google は「サンタを追いかけよう」のエンジンをアップグレードし、ほとんどのシーンでオフライン体験をサポートするようにしました。 YouTube 動画に基づくシーンやサンタのライブ ロケーションを扱うシーンは除きます。もちろん、北極に直接関係している場合に限ります。📶☃️
チャレンジ
サンタには、スマートフォン、タブレット、パソコンでうまく動作するレスポンシブ デザインが組み込まれています。図案化されたビジュアルやホリデーをテーマとしたオーディオなど、優れたマルチメディアでユーザーを楽しませてくれます。 しかし、「サンタを追いかけよう」の通常のビルドは数百 MB に及びます。これには次のような理由があります。
- サンタは 35 以上の言語でサポートされているので、多くのアセットを複製する必要がある。
- プラットフォームが異なれば、対応しているメディアも異なります(例: mp3 と ogg)。
- マルチメディア ファイルが異なるサイズや解像度で提供されることもあります。
サンタのエルフも 12 月は一生懸命働き、1 か月を通して重要なアップデートを新たにリリースします。つまり、ユーザーのブラウザですでにキャッシュされているアセットは、再度アクセスするたびに更新しなければならない場合があります。
課題:
- さまざまな「シーン」に対応する大規模なマルチメディア リソース
- 1 か月を通してリリースされた変更
...その結果、シンプルなオフライン戦略が適さない結果となる。
Polymer で作られたサンタ
サンタをオフライン PWA にアップグレードした方法を見る前に、サンタの全体的なデザインについて説明する価値があります。
サンタは、最初は Polymer 0.5 で記述されたシングルページ アプリケーションですが、今では Polymer 1.7 にアップグレードされています。 サンタは、ルーター、共有ナビゲーション アセットなど、共通のコードセットで構成されています。 また、多くの独自の「シーン」があります。
各シーンには異なる URL(/village.html
、/codelab.html
、/boatload.html
)でアクセスできます。これは独自のウェブ コンポーネントです。ユーザーがシーンを開くと、必要なすべての HTML とアセット(画像、音声、CSS、JS)がプリロードされます。これらのアセットは、サンタを追いかけようのリポジトリの /scenes/[[sceneName]]
にあります。その間は、進行状況を示すわかりやすいプリローダーがユーザーに表示されます。
このアプローチでは、ユーザーに表示されないシーン(大量のデータ)のために不要なアセットを読み込む必要がなくなります。また、すべてのシーンに必要なすべてのアセットの内部「キャッシュ マニフェスト」を保持する必要があります。キャッシュ マニフェストは、ファイル名からその内容の MD5 ハッシュへのマッピングを格納する JSON ファイルです。
使用したアイテムを読み込む
このモデルでは、サイト全体を一度にプリロードするのではなく、ユーザーが訪問するシーンに必要なリソースのみを提供することで、帯域幅を節約します。サンタ トラッカーは、読み込み時ではなく実行時にカスタム要素をアップグレードする Polymer の機能を活用します。次のコードについて考えてみましょう。
<lazy-pages id="lazypages" selected-item="{{selectedScene}}" ... >
<dorf-scene id="village" route="village" icon="1f384" permanent
mode$="[[mode]]"
path$="scenes/dorf/dorf-scene_[[language]].html"
class="santa-scene" allow-page-scrolling></dorf-scene>
<boatload-scene route="boatload" icon="26f5"
path$="scenes/boatload/boatload-scene_[[language]].html"
loading-bg-color="#8fd7f7"
loading-src="scenes/boatload/img/loading.svg"
logo="scenes/boatload/img/logo.svg"
class="santa-scene"></boatload-scene>
サンタを追いかけようは、次のステップでシーン(boatload-scene
:
- すべてのシーン要素(
<boatload-scene>
を含む)は最初は不明であり、すべてHTMLUnknownElement
としていくつかの追加属性として扱われます。 - 選択したシーンが変更されると、
<lazy-pages>
要素に通知されます。 <lazy-pages>
要素はシーンの要素とpath
属性を解決し、HTML インポートscenes/boatload/boatload-scene_en.html
を読み込みます。これには、Polymer 要素とその依存要素が含まれます。- わかりやすいプリローダーが表示されます。
- HTML インポートが読み込まれて実行されると、
<boatload-scene>
は本物の Polymer 要素に透過的にアップグレードされ、ホリデー シーズンを盛り上げます。🎄🎉
このアプローチには課題があります。たとえば、重複するウェブ コンポーネントを含めたくありません。2 つのシーンで共通の要素(paper-button
の場合は、ビルドプロセスの一環として取り除き、代わりにサンタの共有コードに追加します。
オフライン設計
「サンタを追いかけよう」は、Polymer と lazy-pages
を使ってすでにシーンに分割されています。さらに、各シーンには独自のディレクトリがあります。サンタを追いかけようの Service Worker は、ユーザーのブラウザでオフラインで実行されるオフライン処理を可能にするもので、共有コードと「シーン」の違いを認識できるように設計されています。
Service Worker の背後にある理論とはサポートされているブラウザでユーザーがサイトを読み込むと、フロントエンド HTML は Service Worker のインストールをリクエストできます。サンタを追いかけようの場合、Service Worker は /sw.js
にあります。これにより、サンタの共有コードがすべて事前キャッシュされる install
イベントが発行されます。そのため、実行時には何も取得する必要はありません。
インストールすると、Service Worker はすべての HTTP リクエストをインターセプトできます。「サンタを追いかけよう」の場合、意思決定フローは以下のようになります。
- リクエストはすでにキャッシュに保存されていますか?
- では次に、キャッシュに保存されたレスポンスを返します。
- リクエストがシーン ディレクトリ(scenes/bowload/宛先ボートロード-scene_en.html など)と一致していますか?
- ネットワーク リクエストを実行し、結果をキャッシュに保存してからユーザーに返します。
- それ以外の場合は、通常のネットワーク リクエストを実行します。
今回のフローと install
イベントにより、ユーザーがオフラインの場合でもサンタを追いかけようを読み込むことができます。ただし、利用できるのは、ユーザーが以前に読み込んだシーンのみです。
これは、ゲームをリプレイしてハイスコアを獲得するのに最適です。
よく観察していると、Google のキャッシュ保存戦略ではコンテンツの変更が許容されない場合があります。ファイルがユーザーのブラウザのキャッシュに保存されると、その後変更されることはありません。詳しくは後で説明します。
ライブでやる
先ほども話したように、サンタの妖精は 12 月も一生懸命働いています。そのため、12 月中に新しいアップデートをリリースしなければならないこともよくあります。「サンタを追いかけよう」のリリースが作成されると、次のような固有のラベルが付けられます。v20161204112055
: リリースのタイムスタンプ(2016 年 12 月 4 日の 11:20:55)。
このラベル付きリリースでは、すべてのファイルの MD5 ハッシュを生成し、「キャッシュ マニフェスト」に保存します。最新の SSD(ソリッド ステート ディスク)であれば、ビルドプロセスに数秒しかかからないからです。
各リリースは、Google の静的キャッシュ サーバーの一意のパスにデプロイされます。つまり、古いリリースは削除されません。つまり、新しいリリースの後は、変更されていなくてもすべてのアセットが異なる URL を持つことになります。ブラウザや Service Worker でキャッシュされたものは、何か追加作業を行わない限り、無用になります。
また、「prod」リソースという新しいバージョンの(サンタのインデックス HTML および Service Worker)もデプロイします。これらは https://santatracker.google.com/ で公開されています。これにより、古いバージョンが上書きされます。
サンタ トラッカーが読み込まれるたびに、ブラウザは更新された Service Worker を確認し、利用可能な場合は取得します。この例では、リリースごとに 1 バイトの異なるコードが生成されます。ブラウザはこれをアップグレードとみなし、新しい install
イベントを実行します。
この時点で、ユーザーのブラウザでは、新しい「キャッシュ マニフェスト」を参照します。これはユーザーの既存のキャッシュと比較され、アセットに異なる MD5 ハッシュがある場合はキャッシュから削除され、ブラウザに再取得するように求められます。ただし、ほとんどの場合、キャッシュに保存されたコンテンツはほとんど同じか、わずかな違いがあります。
サンタ トラッカーでは、Service Worker をアップグレードすると、ユーザーのブラウザは直ちに再読み込みされます。
オフライン ブラウジング エクスペリエンス
もちろん、UI に変更を加え、オフライン エクスペリエンスに対応するとともに、ウェブサイトでオフライン機能があることを想像していないユーザーが理解しやすくする必要がありました。
オフライン ブラウジング中は、小さなバナーが表示されます。 キャッシュされていないシーンはすべて「フリーズ」し、クリックできません。 これにより、ユーザーは利用できないコンテンツにアクセスできなくなります。
サンタ追跡は、サンタの API に定期的にリクエストを行います。リクエストが失敗またはタイムアウトした場合、ユーザーはオフラインであるとみなされます。ここでは、ブラウザの組み込み navigator.onLine
プロパティではなく、この API を使用します。これにより、ユーザーがオンラインかどうかのみが通知されます。(Lie-Fi とも呼ばれます)。
国際的なつながり
ユーザーの大多数が英語(次に日本語、ポルトガル語、スペイン語、フランス語が続く)を話すが、サンタは 35 を超える異なる言語で作成およびリリースされている。
ユーザーがサンタを追いかけようを読み込む際、Google はブラウザの言語とその他の手がかりを基に、配信する言語を選択します。大多数のユーザーがこの言語を上書きすることはありません。ただし、ユーザーが選択ツールで新しい言語を選択した場合、Google はこれをアップグレードが利用可能なものとして扱います。これは、新しいバージョンのサンタ トラッカーが利用可能になったときのケースと同様です。
言い換えると、Service Worker 向けの「サンタを追いかけよう」の現在のバージョンは、実際には (build,language) のタプルです。
ホーム画面に追加
サンタはオフラインで動作し、Service Worker を提供するため、対象ユーザーはホーム画面にこのアプリをインストールするよう求められます。 2016 年には、ホーム画面アイコンからの読み込みが約 10% を占めていました。
まとめ
サンタ追跡をオフライン PWA に迅速に変換できたことで、既存のシーン設計により、Polymer とウェブ コンポーネントを簡単に使用できるようになりました。これにより、信頼性の高い魅力的なエクスペリエンスを実現できるようになりました。また、Google のビルドシステムを利用して効率的なアップグレードを行い、変更されたアセットのみを無効にします。
サンタの大部分はカスタム開発されたソリューションですが、その原則の多くは Polymer プロジェクトのアプリツールボックスで確認できます。新しい PWA をゼロから作成する場合は、このデモを確認することをおすすめします。また、フレームワークに依存しないアプローチをお探しの場合は、ワークボックス ライブラリをお試しください。