PWA（Progressive Web Apps）について【備忘録】

# 概要
備忘録。

# PWA（Progressive Web Apps）について
 PWAとは、モバイル端末上で、「Webアプリ」を「見た目上ネイティブアプリのように使用」するための仕組みである。Googleが提唱している。特徴を以下のような言葉で表している。ただし、よく日本語ブログで書かれるPWAの参考機能として「プッシュ通知」が挙げられるが、厳密なところ「プッシュ通知」はPWAの要件ではない。

- Fast：応答性が良い
- Integrated：ネイティブアプリのようにホーム画面に追加可能
    - これをするには「manifest.json」の定義が必要
- Reliable：不安定なネットワークでも素早くロード
- Engaging：ユーザが必要とすること（プッシュ通知など）を容易に実装可能

<!--
## 機能
- ユーザーの手元の端末にインストール可能
- キャッシュの利用
- プッシュ通知
- 検索結果やURLから、通常のサイトと同じようにアクセス
-->

# Service Workerについて
　Service Workerとは、ブラウザがWebページとは別にバックグラウンドで実行されるJavascript環境である。Service Workerはイベント駆動であり、Webページと異なるライフサイクル上で動作する。DOMに直接アクセスできない。
　次の図は最初のインストール後のService Workerのライフサイクルである。

![sw-lifecycle.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159492/f48b95c5-0be2-26c0-0e58-0419bc5a44e4.png)


## 前提条件

- ブラウザがService Workerに対応
    - Chrome
    - Firefox（プライベートブラウジングモードでは動作しない）
    - Opera
    - Edge
- WebサイトがHTTPSに設定
    - 例外として、localhostでは動作する。


## ライフサイクル
　Service WOrkerには以下のようなライフサイクルがある。

- インストール
- 有効化(activate)

　ユーザがService Workerが制御するサイトにアクセスするとService Workerがダウンロードされる。その後、ダウンロードは24時間ごとに行われる。ダウンロードが新しい場合、既存のService Workerとバイト単位に比較して異なっていた場合や、サイトで最初のService Workerが見つかった場合はインストールが試みられる。


## イベント
　ここで、調査する限りの登録できるイベントを以下に列挙する。基本的にはイベント処理系は何でもよい？

- install
- activate
- fetch：指定されたリソースに対してアクセスがあったとき
- message：GUI側からService Workerへメッセージ発行されたとき
- push：プッシュ通知を受け取ったとき
- notificationclick：表示されたプッシュ通知を開いた（クリックした）とき


## チェックリスト
　GoogleからPWAについてのチェックリストが出ている。
　基礎的なチェックリストは以下の通り。これは後述する評価ツールにてチェック可能である。「典型的なPWAにおけるチェックリスト」として追加してチェックリストがあるが、これは使用する機能によってチェックするかどうか変わる。

- Site is served over HTTPS（HTTPS対応）
- Pages are responsive on tablets & mobile devices（モバイル端末でも利用可能）
- All app URLs load while offline（オフライン利用可能）
- Metadata provided for Add to Home screen（ホーム画面に追加可能）
- First load fast even on 3G（初期利用時3G環境下での高速利用）
- Site works cross-browser（クロスブラウザ対応）
- Page transitions don't feel like they block on the network（低速ネットワーク化でもページ遷移が高速）
- Each page has a URL（個々のページがURLを介してディープリンク可能）


# 開発環境

項目 | 内容
--- | ---
言語 | Javascript/HTML5
パッケージ管理 | npm
IDE | PWA Builder/Brackets
評価ツール | Lighthouse

# 設計メモ
　基本的にCDN利用はしない前提の設計になる？
　イベントの登録が主な設計？


## オフライン対応

基本は以下のイベントを登録する必要がある(Cashe APIとFetch APIを使用)。詳細は[ここで](https://laboradian.com/create-offline-site-using-sw/)。

- install
- activate
- fetch

# 所感
　「ネイティブアプリのように」という点だが、見た感じとしてはホーム画面またはデスクトップ上に「webページのショートカット」といった様子。「オフライン動作」というのは、キャッシュを用いて、再度同じサイトをアクセスした際には、バイトサイズを比較して違いがあればFetchするという動作をする？ため、オフライン時はキャッシュにあるファイルを用いるという動きをすると推定。ブラウザのためのキャッシュを利用できるというのが利点に感じる。
　Service Workerのソースコードを見ると基本的にはイベント登録／処理がメインであるので、オフライン対応以外では、DOMに関わらないようなイベント（そんなものが多くあるのかどうかは分からない）には良いのかと思う。

# 用語
- ディープリンク：特定の画面に直接遷移するリンク

# 参考
- Web Fundamentals：[https://developers.google.com/web/fundamentals/?hl=ja#fast](https://developers.google.com/web/fundamentals/?hl=ja#fast)
- Progressive Web App Checklist：[https://developers.google.com/web/progressive-web-apps/checklist](https://developers.google.com/web/progressive-web-apps/checklist)
- Infrequently Noted：[https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/](https://infrequently.org/2015/06/progressive-apps-escaping-tabs-without-losing-our-soul/)
- はじめてのLighthouse。どんな指標があるのか調べてみた。(Qiita)：[https://qiita.com/TanakanoAnchan/items/01c02a5bfae4c04465e5](https://qiita.com/TanakanoAnchan/items/01c02a5bfae4c04465e5)
- ラボラジアン：[https://laboradian.com/create-offline-site-using-sw/](https://laboradian.com/create-offline-site-using-sw/)
- Service Worker(Qiita)：[https://qiita.com/propella/items/6500f76c9c1521878a6b](https://qiita.com/propella/items/6500f76c9c1521878a6b)
- Service Worker 初心者入門、概要から使い方まで[https://webbibouroku.com/Blog/Article/serviceworker#outline__1](https://webbibouroku.com/Blog/Article/serviceworker#outline__1)