Yahoo! JAPANトップページ(スマートフォン)におけるPWAの取り組み〜ホーム画面追加編〜

  • このエントリーをはてなブックマークに追加
Yahoo! JAPAN Tech Advent Calendar 2018の19日目の記事です。一覧はこちら

概要

Yahoo! JAPAN Tech Advent Calendar 2018の12月19日目を担当します、
Yahoo! JAPANトップページ(スマートフォン)のエンジニアをやっている神野(@miracletshirt09)です。よろしくおねがいします。

当記事においてはYahoo! JAPANトップページ(スマートフォン)に置けるPWAに関する取り組みをご紹介させて頂きます。

PWAとは

はじめにPWAの説明を致します。
すでにご存知の方は「Yahoo! JAPANトップページ(スマートフォン)に置けるPWAの取り組み」まで読み飛ばして頂いて大丈夫です。

PWAの概要

PWAとはProgressive Web Appsの略でGoogleが提唱する新しいWebアプリケーションの概念です。Progressiveとは直訳すると「革命的」「(段階的な)前進」という意味です。
後述するPWAの技術を取り入れるとネイティブアプリケーション(やデスクトップアプリケーション)に近いUXを獲得することができます。

詳しくは以下のサイトをご確認下さい。
https://developers.google.com/web/progressive-web-apps/

PWAのメリット

PWAのメリットは「Webアプリケーションのメリットをそのままにネイティブアプリケーションの高度なUXを獲得できる」ことです。
「Webアプリケーションのメリット」と「ネイティブアプリケーションの高度なUX」の具体例は以下の通りです。

Webアプリケーションのメリット

  • 利用するハードルが低い
    • 特別な動作環境を用意する必要がない
    • アプリケーションのインストールが不要
  • 提供の容易さ
    • 端末に専用のアプリケーションを配信する必要が無い
    • アプリケーションの更新が容易である
  • 広くリーチできる
    • 検索可能性
      • 検索エンジンにインデックスされる
      • 検索エンジンから直接アプリケーションを起動できる

総じてユーザ側から見ても、サービス提供者側から見ても「手軽である」ということが言えると思います。

ネイティブアプリケーションの高度なUX

以下に記載するのはPWAの技術を利用することで獲得できる(今まではネイティブアプリケーションでしかできなかった)UXです。

  • ホーム画面にそのアプリケーション専用の起動アイコンを設置できる
  • オフラインでの操作 (※1)
  • キャッシュを用いた高速な動作 (※1)
  • Push通知 (※2)

※1 PWAの技術を利用しなくてもできますが非常に実装のハードルが高いです
※2 一部のブラウザには実装されていません

ネイティブアプリケーションができることをすべてWebアプリケーションで実現できるわけではないですが、PWAの登場によりその差は縮んできていると思われます。

国内外のPWA導入事例

以下のサイトがPWAの対応がされています。

弊社のサービスもいくつかPWAの対応がされています。

PWAの技術要素

PWAには主に以下の技術要素があります。

Service Worker

Service WorkerはPWAの根幹をなす技術で、Webページのバックグラウンドで実行されるスクリプトになります。
Service Workerを用いることで、キャッシュ/オフライン対応、バックグラウンド同期、Push通知など今までネイティブアプリケーションでなければ実装できなかった機能をWebアプリケーションに実装することができます。

Service Workerには以下のような特徴があります。

  • Webページ上のJavaScriptとは異なるライフサイクルで動作する
  • データを保持できない(ライフサイクル間でデータを共有する場合はIndexedDBなどを利用する)
  • DOMの操作ができない
    • Service Workerが取得したデータをページに反映させる場合はIndexedDB、CacheStorageを利用する。
  • WebページとWebサーバ間のプロキシとして動作する
  • JavaScriptのPromise(注:JavaScriptの非同期処理を記述する構文です。)を多用する

また、Service WorkerはHTTPSで配信する必要があります。(注:localhostの場合はその限りではありません)

Web App Manifest

PWAの必須要素である「ホーム画面追加(Add to Homescreen/A2HS)」を実現する技術です。Web App Manifestは「ホーム画面追加」された「ホーム画面アイコン」の設定を定義することができます。
Web App Manifestの設定内容を元にブラウザは「ホーム画面アイコン」を生成します。ホーム画面追加アイコンとは、Web App Manifestを元に生成された専用のネイティブアプリケーションです。※ displayがminimal-ui以上の場合

通常のWebクリップとはことなり、そのWebアプリケーション専用のネイティブアプリケーションが生成されるので、各OSのアプリケーション一覧画面にも表示される。

その他機能

現時点でもその他にも以下のような追加機能があります。

  • Credential Management API
    • デバイスを横断したシームレスなログイン機能を実装できる
  • Payment Request API
    • ブラウザ、OSが提供するネイティブUIを用いた決済を実装できる

Yahoo! JAPANトップページ(スマートフォン)に置けるPWAの取り組み

それではYahoo! JAPANトップページ(スマートフォン)におけるPWAの取り組みを紹介致します。
「Android Chromeにおけるホーム画面追加」の実装をしましたので詳しく解説したいと思います。
※ 以降特に指定のない場合はAndroid Chromeにおける動作や仕様の説明になります。

ホーム画面追加

お気づきの方もいらっしゃると思いますが現在、Android ChromeでYahoo! JAPANトップページ(スマートフォン)にアクセスした際にホーム画面追加ができるようになっています。

(Android Chromeにおいては)ホーム画面追加をするためには最低限以下用意する必要があります。

  • Web App Manifest
    • Manifestを記述したmanifest.jsonファイルを用意
    • linkタグでmanifest.jsonファイルを指定
  • Service Worker
    • Service Workerのスクリプトを実装して、ドメイン直下に配置する
    • Webページのロード時にService Workerの登録処理を記述する

それぞれ詳しく解説していきます。

Web App Manifestの解説

Web App ManifestはChrome(PC版)のDevtoolで確認することができます。
右クリック > 検証 > Application > Manifestを開くとそのWebアプリケーションのManifestを確認できます。

Yahoo! JAPANトップページ(スマートフォン)のWebAppManifest
※ Yahoo! JAPANトップページ(スマートフォン)のWebAppManifest

Web App Manifestの実態はmanifest.jsonです。Yahoo! JAPANトップページ(スマートフォン)では以下のような内容になります。

manifest.json

{
  "lang": "ja",
  "short_name": "Yahoo!",
  "name": "Yahoo! JAPAN",
  "icons": [
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y48.png",
      "sizes": "48x48",
      "type": "image/png"
    },
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "https://s.yimg.jp/images/mtop/etc/pwa/y512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "/?fr=top_a2hs_and",
  "display": "standalone",
  "theme_color": "#ff0033",
  "background_color": "#ffffff"
}

Web App Manifestの重要な要素を解説します。

要素名 説明
name Webアプリケーションの名称を指定する。この名称はホーム画面追加時のダイアログやスプラッシュ画面に表示される。
short_name Webアプリケーションの短縮名称を指定する。mini-infobarやホーム画面アイコン下に表示される名称はshort_nameになる。
start_url ホーム画面に追加したアイコンから起動するURL(パスのみ)を指定する。サーバサイドでホーム画面のアイコンから起動したかどうか判定したい場合はGETパラメータを指定する。
display ホーム画面に追加する際のディスプレイモードを設定する。※ 詳しくは後述。
icons ホーム画面に追加するアイコンファイルを指定する。Android Chromeの場合は192x192のサイズは必須となる。

その他にも

  • theme_color (アプリケーションの上部ナビゲーションバーの色を指定)
  • background_color (スプラッシュ画面の背景色を指定)
  • orientation (画面の向きを指定)

といった要素があります。※ 指定をしなくても動作します。

次にdisplayの解説をします。

モード 説明
browser 通常のWebクリップと同じ。ブラウザが起動する。
minimal-ui 通常のWebショートカットではなく、個別のアプリが生成されホーム画面に追加される。ドロワー画面(アプリ一覧画面)にも表示される。minimal-uiはアドレスバーなどの最小のブラウザナビゲーションを提供する。
standalone minimal-uiと同じく個別のアプリが生成される。minimal-uiと異なる点は、アドレスバーなどのブラウザナビゲーションも表示されなくなり、よりネイティブアプリに近いUIとなる。
fullscreen fullscreenはさらにAndroidのナビゲーション(上部下部ともに)も表示されなくなる。ナビゲーションは下からスワイプすると表示される。

※ 上記のdisplayモードはあくまでAndroid Chromeでの指定となっており、iOS Safariやその他ブラウザでは上記の通りにはならないので注意して下さい。

Yahoo! JAPANトップページ(スマートフォン)では上記の中から通常のネイティブアプリケーションライクな操作が可能なstandalone を選択しました。

manifest.jsonが作成できたら、HTMLのhead要素に次のコードを追加します。

<link rel="manifest" href="/manifest.json">

ここまで行うとChromeのDevtool上でWeb App Manifestが読み込まれていることを確認できます。
しかし「ホーム画面追加」を行うためには「オフライン対応」を行う必要があるのでこれだけでは「ホーム画面追加」を行うことはできません。次の「Service Workerの用意」の手順に従ってService Workerスクリプトを設定します。

Service Workerの用意

上記と重複しますがホーム画面追加をするためには「オフライン対応」が必要です。
Android Chromeでは「オフライン対応をしている」という条件を満たすためには以下の対応が必要です。

  1. Service Workerにfetchイベントのリスナーが記述されいる
  2. WebアプリケーションにService Workerが登録されている

それぞれ説明していきます。

まずはService Workerスクリプトの作成です。以下のファイルを記述し/sw.jsで参照できるようにします。

self.addEventListener('fetch', function(event) {});

本格的なオフライン対応の実装は不要です。上記のようにfetchイベントのリスナーに空の処理を記述するだけで問題ありません。

次にWebアプリケーションに対してService Workerを登録します。
ページが読み込まれたとき(bodyタグの一番下もしくはbodyのonLoadが発火したタイミングが望ましいです)に以下の処理が実行されるようにJavaScriptを記述します。

window.addEventListener('load', () => {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js').then(registration =>
      console.log('success, scope:', registration.scope)
    ).catch((err) => console.warn('failed: ', err));
  }
});

Service Workerが登録されているかどうかはChrome Devtool > 検証 > Application > Service Workerから確認することができます。

Service Workerのスタータスを確認

ここまで実装をすればホーム画面追加を行うことができます。

動作確認の方法

実機での動作確認の他にPCのChromeでホーム画面追加が正しく行えるかどうか確認する事ができます。
前述した検証 > Application > Manifestを開き、画面右上の「Add to homescreen」をクリックします。

検証 > Application > Manifest

Chromeのアドレスバーの下に「このサイトをシェルフに追加するといつでも使えるようになります [追加]」というナビゲーションが表示されるので「追加」ボタンをクリックします。

追加

するとChromeの「chrome://apps」にWebアプリケーションの起動アイコンを設置することができます。

ちなみにPCでホーム画面追加を行った場合以下のようになります。
※ Chrome 71(現行最新版)でdisplayがstandaloneの場合になります

  • macOSのChrome
    • ランチャー画面にも追加される
    • 起動アイコンをクリックするとWebアプリケーションをChromeで開くことができる
  • WindowsのChrome
    • スタートメニューにも追加される
    • 起動アイコンをクリックするとWebアプリケーションを アドレスバーが無いChrome で開くことができます

苦労したところ

次にYahoo! JAPANトップページ(スマートフォン)のホーム画面追加対応を行って苦労したところをいくつか紹介致します。

対応ブラウザ問題

ホーム画面追加されたWebアプリケーションの動作はブラウザの実装により大きく仕様が変わります。実際にiOS SafariとAndroid Chromeでは追加されたWebアプリケーションの動作は大きく異なります。
そのWebアプリケーションがホーム画面追加をしたときにどの様な操作感になるのか、吟味した上で対応をすることをおすすめします。

Yahoo! JAPANトップページ(スマートフォン)では以下の理由により、iOS Safariでのホーム画面追加対応を見送っています。

  1. 「戻る」の操作ができない
  2. 別ドメイン(サブドメインが異なる場合でも)のリンクをタップした際にSafariにtoAppされてしまう
  3. Safariと(Cookieなどの)認証情報を共有していない

特に2と3は致命的で、ログイン認証のページのドメインが異なる場合はログインした状態でWebアプリケーションを利用できなくなってしまいます。
この様に各ブラウザでどのような動作になるかは実際に動かしてみないとわからないことが多いので、リリース前に開発環境等で利用シーンを意識して動作確認を行う必要があります。

ブラウザのバージョンアップ問題

ホーム画面追加(やPWAの技術要素)は比較的新しいブラウザ機能になりますので、仕様変更や機能の改善が頻繁に発生します。

特に苦労したのがChrome 68のバージョンアップです。
詳しくは以下のリンクをご参照いただきたいのですが、ホーム画面追加を訴求するブラウザ機能が大幅に仕様変更になりました。

Changes to Add to Home Screen Behavior

簡単に説明すると変更点は以下の通りです

  1. A2HS Bannerの廃止
  2. mini-infobar、A2HS Dialogの追加
  3. 訴求の表示抑制不可

ホーム画面追加の訴求はChromeが任意のタイミングで行うのですが、A2HS Banner以前の訴求はWebアプリケーション側で表示抑制をすることができました。
Yahoo! JAPANトップページ(スマートフォン)でも特定のタイミングではホーム画面追加の訴求(A2HS Banner)を非表示にしていたのですが、Chrome 68以降ではそれができなくなりました。

また、訴求のタイミングも異なります。Chrome 67未満(A2HS Banner)では「一週間のうちに5分以上間隔を開けて2回以上アクセスしたとき」に訴求が表示されたのですが、mini-infobarはホーム画面追加の条件(Web App Manifestがあり、オフライン対応がされている)が整えば常に表示されるようになります。(すでにホーム画面追加をしている場合やmini-infobarをxボタンで閉じている場合はその限りではない)

Chrome 67未満(A2HS Banner)ではChromeが行う訴求の表示を遅らせて独自の訴求(Yahoo! JAPANトップページ(スマートフォン)ではモーダルで表現しました)を行うことができたのですが、Chrome 68以降ではそれもできなくなりましたのでその機能はお蔵入りとなりました。

上記以外でもホーム画面に追加されたWebアプリケーションの動作がChromeのバージョンにより微妙に異なるなど、機能の変更が頻繁に行われています。
通常のWebアプリケーションを提供する以上にブラウザのバージョンアップには敏感になる必要があります。

Google Playアカウント問題

これはいくら調べてもネット上で出てこないのでChromeの特定バージョンにおけるバグの可能性もあるのですが、Google Playにログインをしていない状態でホーム画面追加をすると、ホーム画面に追加したWebアプリケーションがアプリとして認識されていない状態になります。
displayはstandaloneで、動作上は通常のホーム画面追加したWebアプリケーションと同じなのですが、ドロワー画面に出てこない、そのURLにChromeでアクセスした際にかつmini-infobarが表示されてしまいます。(またホーム画面アイコンに小さいChromeのアイコンが表示されます)

偶然Google Playにログインしていない状態で動作確認をして見つけた動作になります。原因がわかるまで苦労しました。

何故か日本語のページには特定の情報が記述されていない

ホーム画面に追加したWebアプリケーションからのアクセスなのか、それとも通常のブラウザからのアクセスなのかを判定して処理を変えている場所があります。Yahoo! JAPANトップページ(スマートフォン)では2種類の方法でそれを実装しています。

  1. GETパラメータによるサーバサイドでの判定
  2. window.matchMedia('(display-mode: standalone)').matches によるクライアントサイドでの判定

上記の2に関しては何故か日本語ページ(※)には判定方法が載っていません。クライアントサイドでの判定方法を探すのに苦労しました。
(他の技術でも言えると思いますが)基本的に英語で情報を集めたほうが良さそうです。

※ 当該ページ → Add to Home Screen
※ Englishと日本語で比べてみて下さい。

課題と今後対応していきたいこと

Yahoo! JAPANトップページ(スマートフォン)のホーム画面追加対応の紹介をさせて頂きました。
上記で説明させて頂いた通り、通常のWebアプリケーションよりもブラウザへの依存度が高まるという課題がありますので今後もChromeの動向を追い続けると共に、その他ブラウザへの適応も慎重に検討していきたいです。

まだService Workerの本領を発揮するような機能(キャッシュ、オフライン対応、バックグラウンド同期、Web Pushなど)が実装されておりませんので、今まで得たPWAに関する知見を元に、今後もPWAの技術要素を段階的に実装していきたいと思います。

所感

私がプロダクション環境でPWAのホーム画面追加を実装した所感は以下の通りです。

PWAのメリット・デメリット

繰り返しになりますが以下がPWAのメリット・デメリットかと思います。

  • メリット
    • Webアプリケーションのメリットをそのまま活かせる
    • ネイティブアプリケーションに近いUXを実現できる
  • デメリット
    • 通常のWebアプリケーションよりもブラウザへの依存度が高くなるので注意が必要
    • ブラウザの仕様が頻繁に変わるので追従していく必要がある

専用アプリケーションの配信が不要ですので変更を加えることがネイティブアプリケーションよりも容易です。また、アプリケーションプラットフォームによる審査が不要なことからPWAは比較的外部要因によるリードタイム延長のリスクが低いです。新しくサービスを始める場合は(どうしてもネイティブアプリケーションでなければ実現できない体験がある場合を除いては)PWAから小さく始めるというのも有効な選択肢の一つではないかと思います。※ 無論サービスの特性によってはPWAが向かない場合もあるかと思います。

既存のWebアプリケーションをPWA化する上での注意点

既存のWebアプリケーションにPWAの技術(特にホーム画面追加)を導入する場合は以下の点に注意を払う必要があります。

  • ホーム画面追加したWebアプリケーションの動作に問題は無いか?
    • ブラウザ機能が制限されることによる影響はどの程度あるのか?
    • 利用シーンを意識して現行のUXを損なわないか?
  • ブラウザ間の差異をどこまで許容するのか?
    • どのブラウザを対象とするのか?
    • 非対象ブラウザをどの様に扱うのか?

総じて現在ユーザから評価を得ている部分が損なわれないかを実際に手で触って確認する必要があるかと思います。
ホーム画面追加だけでしたら先述の通り容易に実装をすることができます。しかし、通常のブラウザとは体験が異なるということを考慮して慎重に検証を重ねて行くほうが良いと思います。

最後に

今回の記事では、PWAの概要からYahoo! JAPANトップページ(スマートフォン)におけるホーム画面追加対応の事例を紹介させていただきました。
当記事がPWAの技術を採用するキッカケや現在対応されている方の手助けになれば幸いでございます。今後もPWAの技術に関して情報発信していけるように精進して参ります。
最後までご覧いただきありがとうございました。

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加