やっていこう。PWA

2015年にPWAが提唱されてから3年以上が過ぎました。
2015年6月に公開された「[Progressive Web Apps: Escaping Tabs Without Losing Our Soul](https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/
)」に Progressive Web Apps の初期のコンセプトが書かれています。

記事中には、PWAによって「**deliver an even better user experience** (さらに優れたユーザーエクスペリエンスを実現)」 と書かれている通り、様々なWebの技術により、最近のWebサイトはとてもUXが良くなってきました。これもじっくりと期間をかけて、様々な技術者がPWAを取り組んでいっているからだと思います。

そして2015年11月に開催された「Chrome Dev Summit 2015」のキーノートで発表されてPWAは話題になりました。

https://codelabs.developers.google.com/chrome-dev-summit/

この動きは今後も継続していくことでしょうし、Webはもっとより良いものになっていくでしょう。

そんなPWAをやっていくためには、その前提知識が不可欠です。今のPWAでは何ができるのか、そして今後はどのようなことが可能になっていくのかをまとめてみます。

※この記事は https://speakerdeck.com/oliver_diary/yatuteikou-pwa の資料をもとに作られています。

## PWAとは
PWA は Progressive Web Apps の略です。**モバイルに限らず**デスクトップの両方でインストール可能であり、アプリと同等の体験を提供します。

**Reliable**, **Integrated**, **Fast**, **Engaging** などのUXを兼ね備えたWebアプリのことであり、特定の技術のことではないです。

ちなみに **Reliable**, **Integrated**, **Fast**, **Engaging** をまとめて「**FIRE**」と呼ばれているらしいです。もう少し FIRE を掘り下げていきましょう。

- Reliable
ネットワークの状態が不安定な場合でも瞬時に表示し、オフラインでも**downasaur**が表示されないような状態。
Service Workerを用いて、重要なリソースを事前にキャッシュしておくことで、ネットワークの状態に関係なく即座に読み込むことが可能。

<img width="899" alt="Screen Shot 2019-05-15 at 2.23.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/fb04dc5f-9690-3fc3-1131-7b495f9f8905.png">

- Integrated
体験をよりデバイス、OSに合わせた形にし、Webを意識させないということ。
すなわちブラウザを起動しなくてもWebサイトを開ける、みたいな状態。
  - ホーム画面に追加
  - フルスクリーン表示
  - などなど

- Fast
アニメーションでが滑らかで、操作にすばやく反応してくれるような状態。
ちなみに、ページのロードに3秒以上かかると、**53%**のユーザーがサイトを離脱するらしい。

- Engaging
アプリのように感じられて、のめり込まれるようなUXがある状態
  - アプリストアを必要とせずにユーザーの**ホーム画面に追加**される
  - **プッシュ通知**でユーザーに通知を届けることができる
  - などなど

## 最近のPWA
PWAの動きはOSやブラウザによって大きく異なります。AndroidやiOS、MacやWindows、LinuxにおけるPWAの動きを振り返っていきましょう。

### ざっくりとしたAndroid版Chromeの動き
- Google Chrome 56(2017年2月)
    - WebAPKによってWebをアプリ化できるようになる
- Google Chrome 68(2018年7月)
    - Add to Home Screen (A2HS) から Mini-infobar へ
- Google Chrome 72(2019年1月)
    - Trusted Web Activity(後述)
        - PWAを Google Play にアプリとして登録することができる!

特にA2HS から Mini-infobar へ変わった時は、画面を圧迫せずにホーム画面に追加ポップアップが出るようになりました。
<img width="470" alt="Screen Shot 2019-05-16 at 0.12.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/d74c57a1-76fb-7fbb-7e4d-cea317ac9a84.png">

### ざっくりとしたデスクトップ版Chromeの動き
- Google Chrome 67(2018年5月)
    - Chrome OSをPWAに対応
- Google Chrome 70(2018年10月)
    - Windows / LinuxをPWAに対応
- Google Chrome 73(2019年3月)
    - macOSをPWAに対応

2018年から2019年にかけてデスクトップ版のChromeはPWAに対応してきました。現在では、主要３つOS全てで利用可能で、PWAの恩恵を受けることができます。

現在は右上のメニューバーからアプリとしてインストール可能なのですが、今後はURLバーにボタンが設置されるとの情報もあります。楽しみですね。

<img width="532" alt="Screen Shot 2019-05-16 at 0.17.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/42091993-25ed-6a4d-9847-1eb1275f7a0b.png">

### ざっくりとしたiOSの動き
- iOS11.3（2018年1月）
    - iOSがPWAに対応
    - Service Worker が使えるようになった
    - 「ホーム画面に追加」からインストール可能
    - **Oauthログイン時にSafariに飛ばされる**
- iOS12.2（2019年3月）
    - Web Share API に対応
    - ジェスチャーによるナビゲーション（スワイプで進む、戻るなど）
    - マルチタスク時にも状態を維持（**Oauthログインが可能になった**）

iOS版のPWAも着々と対応が進んでいます。特にiOS12.2では **Oauthログイン** が可能になったことが大きいです。例えばTwitterログインが必要なサービスがあった時に、その時点でiOSのPWAは候補から外れてしまっていたのですが、それがなくなったのはとても大きいですね。

まだPush通知や、様々なAPIはChromeに劣りますが、今後も様々なAPIに対応していくでしょうし、楽しみです。

## Progressive Web App Checklist について
PWAの基本的な要件は https://developers.google.com/web/progressive-web-apps/checklist ここに書かれている通りです。

**HTTPS必須**だとか、**モバイルフレンドリー**だとか、**ホーム画面追加**だとか、**キャッシング**だとか、結構たくさんあるので１度目を通しておくといいでしょう。

### PWAの必要条件ではないけどWebで出来ること
PWAを実装する上で必ず必要ではないけれど、PWAにしていく上でアプリに近づけていくためのAPIはたくさん存在します。現在使えるものの一部は以下の通りです。

- Push API
 - Push通知に関するAPI
- Web Share API
    - ページシェアを提供するAPI
- Payment Request API
    - 決済フローに関するAPI
- Web Bluetooth
    - Bluetooth機器を制御できる
- Camera API
    - カメラに関するAPI
- Geolocation API
    - 位置情報を取得
- Web Audio API
    - オーディオの再生制御
    - マイクの入力など
- Device Orientation Event
    - 加速度センサー・ジャイロセンサーの制御
- getInstalledRelatedApps
    - ネイティブアプリのインストール確認

などなど、他にも様々なAPIが存在します。Google I/Oでの発表スライドでは以下のようなスライドがありました。
<img width="1004" alt="Screen Shot 2019-05-13 at 1.07.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/2ab6af95-7a1a-e510-ce86-c014f1789e1e.png">

## PWAを目指す上で大事だと感じていること
PWA化していく時に、UX向上のため、様々な施策が必要です。特に個人などで開発しているときに、PWA化しただけで満足してしまい、その先のことを考えないがために、結果としてUXが悪くなってしまう、というケースは起こり得ます。

そうならないように、しっかりと吟味した上で実装していくことが大事であり、個人的に考えていることを２つ挙げようと思います。

### どのようにしてユーザに「通知を許可」させるか

どのようにしてユーザに「通知を許可」させるかは非常に難しい問題であり、よく考えなければいけないです。皆さんは、初めて訪れたサイトで通知を許可したことありますか？

自分は少なくともすぐに拒否を押してしまいます。エンジニアではない人に対して「通知を許可させる」のは、とても難しいです。特に新規サービスでは。

そして、一度拒否したブラウザを許可にするのも、とても難しいです。

なので最近見る手法が、**独自のモーダルやポップアップを挟むことによって、一度それを出してから、通知の許可を押させ、そのあとでChrome側の通知ポップアップを出す** という手法です。

これなら仮に拒否したとしても、また次の機会に許可するかもしれないという希望は生まれます。けど、やりすぎるとうざいので注意が必要ですが。。。

### Service Workerによるコンテンツのキャッシュ戦略
キャッシュはサービスごとに深く考えなければいけないです。例えば、**追記（更新）が多いメディア**の場合、コンテンツのキャッシュをどうするのかなどです。

どのようにしてコンテンツの追記（更新）を伝えるのか、考えてみましょう。

一つ考えられる方法は「クエリストリングを使う」という方法ですが、**SNSでURLが共有されていた場合やお気に入りに追加されていた場合に困る**のであまり使いたくありません。

また、他の方法としては「更新確認用のリクエストを飛ばす」などが考えられますが、この場合は「更新があった場合に２回リクエストが発生してしまう」、「しかも並列に処理できないためネックとなる」などの問題が考えられます。

なので、こういったケースの時には**ネットワークファースト**で実装するのが良いでしょう。

例えば、**「通信環境が担保されているならサーバーから取得、オフラインならキャッシュから取得にする」**や、**「取得に（例えば）1秒以上かかった時点でキャッシュに切り替える」**などが考えられます。

ここら辺の考えは Workbox の戦略が参考になる部分があるので目を通しておくと良いでしょう。
https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies

## PWAにまつわる技術たち
### PWAに関するフレームワークやサービスたち

- Ionic
    - スターターテンプレートレベルでPWAをサポートしている
- Flutter
    - Google I/O 2019 でPWAに対応していく方針が発表
- Nuxt.js
    - 個人的にオススメ。最近はいつもお世話になっている。
    - Workbox が内包されているため扱いやすい。OneSignal を使ったプッシュ通知にも対応。
- WorkBox
    - Sevice Workerにおける、複雑なライフサイクルをライブラリ側でやってくれ、キャッシュ管理を便利にしてくれるもの( https://developers.google.com/web/tools/workbox/ )
- OneSignal
    - 簡単にPush通知を可能にするサービス( https://onesignal.com/ )

### PWA Builder
https://www.pwabuilder.com にて公開中のマイクロソフトが公開しているPWAの開発支援ツール。ManifestやService Worker用のコードなど、様々なコードを自動生成してくれるので便利です。

### TWA (Trusted Web Activity)
概要は https://medium.com/@firt/google-play-store-now-open-for-progressive-web-apps-ec6f3c6ff3cc に書かれています。
Android 版 Chrome 72 のリリースとともに正式に利用可能になり、**Chrome が提供する機能である TWA 上で動くという仕組み**になっています。

手順は少し多いが、これによりPWAをGoogle Play Storeに載っけられます。要するにPWAをAPKにすることができます。Chromeとセッションやストレージ、キャッシュなどは共有しています。

PWAだけではカバーしきれなくなった部分が出てきたときに、**またゼロから開発する必要性が少なくなる**のが良いと思い、今後の主流になっていくのかもしれませんね。

TWAについては、以下のスライドやブログも見ておくと良いでしょう。

- https://www.slideshare.net/RyuShindo/20190320-pwanight-pwa-to-apk
- https://blog.chromium.org/2019/02/introducing-trusted-web-activity-for.html

公式のやり方は https://developers.google.com/web/updates/2019/02/using-twa に書かれていますが、 https://appmaker.xyz で作るという方法もあります。テストでサクッと試したいときにオススメです。

## Google I/O 2019 にて
Google I/O 2019 では、今後追加される予定の様々なAPIが発表されました。まだ出るかわからないものや、未確定なものがありますが、とてもワクワクするものばかりです。一部を紹介していきたいと思います。

- Web Share Target API v2
  - v1に比べて、ファイルも共有できるようになる
- Shape Detection API
    - 顔検出、バーコード検出、テキスト検出などが可能に
- Badging API
    - アプリアイコンにバッジを付与することが可能に

Badging APIに関しては以下のような記述方法で実装が可能になるようです。リリースが楽しみですね。
<img width="1006" alt="Screen Shot 2019-05-13 at 1.37.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/c73c43e2-03fb-a676-fd98-14e04c2ceec6.png">

- Wake Lock API
    - 操作していない時の画面のロックを防ぐ
- Native File System API
    - ローカルのファイルをわざわざアップロードして、変更してからダウンロードするという手間を無くせる
- Serial API
    - マイクロコントローラや3Dプリンタなどと通信できるようになる
- WebHID
    - ゲームパッドなどのHIDドライバによって制御されていてWebにアクセスできないHIDへの制御が可能に
- Contacts Picker
    - ユーザの連絡先にアクセスできるようになる
- Font Access API
    - ローカルにインストールされているフォントの取得やフォントの詳細にアクセスできる

などなど、たくさんのAPIが発表されてとてもワクワクですね。

<img width="998" alt="Screen Shot 2019-05-13 at 2.01.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/ebcd16de-b53c-d7a0-5ee5-c83303afa3a8.png">

また、これらのAPIは以下のような感じで進んでいくようです。
<img width="998" alt="Screen Shot 2019-05-13 at 2.03.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213538/b0dc38a0-9435-f430-5b6d-10b0c7c3b200.png">

このような感じでWebでできることが増えてきて、PWAの可能性を感じられます。

## 最後に
確実に、着々とPWAは現実的なものになってきていると感じられます。Safariの対応次第では、かなり化けますし、頑張って欲しいところです。

そして、PWAをストアに載っけるのが主流になる時代が来るのかもしれませんし、PWAをより簡単に開発できるプラットフォームが出てきてもおかしくないです。

また、様々なAPIが今後も出てくるので要注目ですし、楽しみです。Webメインで開発している人がWebだけで完結できるのはとても良いことだと思いますし、最高ですね。

このような感じで紹介していきましたが、PWAはもう十分に戦えるレベルにあると考えています。

ぜひみんなも**「やっていこう。PWA」**


## 参考URL
- https://speakerdeck.com/oliver_diary/yatuteikou-pwa
- https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/
- https://codelabs.developers.google.com/chrome-dev-summit/
- https://developers.google.com/web/progressive-web-apps/checklist
- https://developers.google.com/web/tools/workbox/
- https://developers.google.com/web/tools/workbox/reference-docs/latest/workbox.strategies
- https://developers.google.com/web/updates/2019/02/using-twa
- https://www.slideshare.net/RyuShindo/20190320-pwanight-pwa-to-apk
- https://blog.chromium.org/2019/02/introducing-trusted-web-activity-for.html
- https://www.pwabuilder.com
- https://www.youtube.com/watch?v=GSiUzuB-PoI