entry-header-eye-catch.html
entry-title-container.html

entry-header-author-info.html
Article by

pixiv chatstoryのPWA採用事例

ピクシブ福岡オフィスの @ikasoumen です。iOS版が先行してリリースされていたチャットストーリー投稿アプリの「pixiv chatstory」。 昨年の12月から、Android版の提供もはじまりました。

ホーム画面にインストールできるWebアプリ

ネイティブで実装されているiOS版と違い、Androidでは全てHTML + CSS + JSで作られているWebアプリを、Google playストアを経由せずにpixiv chatstoryの公式サイトから直接Android端末へとインストールすることができます。 従来の「ホーム画面に追加」されたWebページと違って、Chromeのヘッダーが非表示になっていたり、URLを開く際にアプリとして選択できたりと、まるでネイティブアプリかのような体験を得られます。

これには、Progressive Web App(PWA)の特徴の一部を利用しています。 細かい説明や定義はGoogleの説明に任せるとして、ざっくりとPWAについて説明すると、これまで実現が難しかった、以下のような機能を使ったWebアプリのことです。

  • Android1 のホーム画面にアプリとしてインストールできる
  • プッシュ通知が送れる
  • オフライン時でも表示できるように、CSSやJSなどのリソースやコンテンツをキャッシュできる
  • など……

とはいえ、まったく新しい技術が必要かというとそうではなく、従来のWebアプリに新しいブラウザのAPIを使って機能が盛り込まれているだけです。 たとえ上記の機能にすべて対応していないブラウザであっても、通常のWebアプリとして使うことができます。

PWAにしてみよう

Android端末へとインストールできるPWAにするには、少なくとも以下の2点を準備する必要があります。

  • Service Worker がサイトにインストールされている
  • Web App Manifest が読み込まれている

上の2点に軽く触れながら、PWAにする手順をおさらいしてみましょう。

Service Worker

通常の JavaScript とは異なるライフサイクルで動作するスクリプトで、以下のような特徴があります。

  • Webサイトにアクセスされるタイミングで インストール する
  • Webサイトにアクセス中でなくても実行できる
  • 定期的にServise Worker自体の更新がチェックされ、更新があればアップデートされる

簡素な Service Worker スクリプトの例

Service Worker自体のライフサイクルに合わせて install, fetchなどの イベントが定義されているので、各イベントに対する処理を記述していきます。 各ライフサイクルの詳細はGoogle のWeb Fundamentalsの記事を読むと一通りわかるかと思います。

インストール

上記の処理を<script>タグ内に直接書いたり、サイトで読み込むJSに入れたりして、Service Worker をサイトにインストールします。

Service Workerの制約

Service Workerのインストールを行うには、以下の制約があります。

  • Service Worker スクリプトが、インストールしたいサイトと同じドメインから提供されている
  • HTTPS でサイトが提供されている

Web App Manifest

Webアプリをアプリケーションとして扱う時の設定を記述できます。以下のような json形式になっており、 "display"プロパティでブラウザのヘッダーを非表示にしたり、"icons"プロパティでインストール時のアイコンを設定したりできます。 こちらも、詳細はGoogle のWeb Fundamentalsを参照していただけると良いかと思います。

Web App Manifest のjsonファイルは、<link>タグで読み込みます。

インストールできるPWAになっているか検証する

Service Worker と Web App Manifestの両方を用意した状態で、Android Chromeで「ホーム画面に追加」すると、アプリの登録名変更ができなくなっています。 ここから、普通のブックマークではなくPWAとして認識されていることが確認できます2

また、ChromeではPWAでのインストールを検証できます。DevToolsのApplication > Manifest > Add to homescreenService WokerとWeb App Manifestが正しく書けているかを検証できます

インストールの体験設計

技術的に実現できるとは言っても、PWAとしてのWebアプリのインストールはまだ普及しているとはいえません。 PWA版のリリースには、以下に挙げるような内容について、どう体験を設計していくかデザイナーや他のメンバーと詰める必要がありました。

  • 快適なユーザー体験のためには、ぜひインストールして使って欲しい
  • インストールしないで使える機能と使えない機能の切り分けが難しい。どのタイミングでインストールしてもらうか?
  • 現在PCではPWAとしてインストールできないため、インストールした時のみ使える機能を提供するとPCでは使えない
  • iOSではアプリ起動時に作っていたAPI Keyはどのタイミングで用意すべきか?

上記について色々頭をひねった結果、pixiv chatstoryの初期リリースでは「ブラウザでのアクセス時はアプリの説明ページを出し、インストール時はiOSと揃える」という方針に落ち着きました。 これは、iOS版と大きく異なるユーザーストーリーを設計・研究した上で実装するのは、非常にコストが高いためです。

現在は、ブラウザでのアクセス時の一部ページで、インストール時と共通のコンポーネントを使っています。 また今後も、ブラウザでのアクセス時でもインストール時の機能を使えるようにしよう!という要望があったときに、柔軟に機能を流用できます。

ブラウザでのアクセス時とインストール時で機能の違いがあるとき、境界を柔軟に引き直せるというのは、 従来のWebアプリ + ネイティブアプリ構成で実現しづらいPWAの魅力の1つかなと思います。

Android PWAにおけるTIPS

最後に、AndroidにインストールしたPWAの挙動について、Web上にあまり情報がなかったものを紹介しておきます。みなさんの実装の助けになればと思います。

シェアURLに遷移するとき、PWAで開かれる

PWAが提供されているドメインのURL(例:https://chatstory.pixiv.net/stories/Xeb0X2K )を開くとき、PWAでインストールされていればPWAで開くことができます。

PWAのアプリが落ちたとき、復帰すると元いたURLを再リクエストする

メモリ不足などでPWAのアプリがキルされたあと再度アプリを起動すると、最後にいた画面に復帰するために、PWAがキル前に居たページのURLをリクエストします。 History APIを使ってフロント側でURLを書き換えている場合、書き換え後のURLをリクエストされてもきちんとレスポンスを返す必要があります。きちんとSingle Page Applicationにしておけ、ということですね。

まとめ

  • PWAを作れば、Androidユーザーに対してWebアプリでもネイティブアプリに近い体験が提供できる。
  • PWAはまだ発展途上。端末にインストールしてもらう場合、どういう体験になるか事前に詰める。

この記事は一緒に開発を進めてくれた @petamoriken にアドバイスをもらいながら執筆しました。ありがとうございます。

ピクシブ株式会社福岡オフィスでは、ユーザーの体験を大事に、新しい技術を積極的に取り入れてサービスを作り上げる仲間を募集しています!


  1. Ver.11.2 までのiOSでは、ホーム画面にインストールしても、ネイティブアプリのように動いてくれません。記事で後述するService Workerが 11.3 から提供される予定なので期待しています。 

  2. 現状ではブラウザのメニュー画面から『ホーム画面に追加』を押してもらう必要がありますが、将来的にホーム画面に追加するボタンをDOM上に提供できる機能がAndroid Chrome に盛り込まれる予定です。参考: Progressive Web Apps: Integrating with Browsers and Operating Systems (Chrome Dev Summit 2017) 

20191219022838
ikasoumen
2016年入社。一度作ったらどのデバイスでも動く(正常な動作を保証するとは言っていない)ので、Webが好きなエンジニア。趣味でiPad Proとpixiv Sketchを使ってイラストを描きつつ、Sketchチームにフィードバックしたりしている。