UdemyでPWA入門をした

クリエイティブ寄りなWeb制作会社でも、**Progressive Web Apps（以下、PWA）**の対応を行う案件が増えてきたようです。

弊社では、`Nuxt.js`で開発する案件が多く、PWA導入の際は「[pwa-module](https://github.com/nuxt-community/pwa-module)」を使用しているようですが、

私感としては、**PWAの知見がないのに、ラッピングされたツールを使用したくありません。**

そこで、「そもそもPWAって何だ？」を学べる教材を探していたところ、Udemyの**『[Progressive Web Apps (PWA) - The Complete Guide](https://www.udemy.com/progressive-web-app-pwa-the-complete-guide/)』**に出会いました。

## コースの概要

* セールで¥1,300の時に購入しました。
* 言語は、**英語**です。字幕も、自動翻訳のみです。
* 制作済みのプロジェクト**「写真投稿アプリ（pwagram）**に対してPWAを導入するために、`Service Worker`を記述していきます。
* `Workbox`等のライブラリに頼らず、スクラッチでの開発です。（後半に少しだけ、`Workbox`の紹介はあります）
* `Single page Application`をベースにしていないので、その辺りの知見がない方でも学べます。
* 既存プロジェクトに対しての実装のため、**書く**よりも、**観る**のほうが適しているコースかもしれません。
 * 課題もありますが、`CacheAPI`のセクションだけでした。
* `CacheAPI`、`IndexedDB`、`Background Sync`、`Web Push`がメインの学習項目。
 * Promise/Fetch API や レスポンシブデザイン についてのセクションもあるが、そこは常識なので飛ばした。
 * データベースやストレージ、アプリサーバ等は、`FireBase`を利用する。


## セクションの流れ

ざっくりメモのため、気になる方は受講を推奨します。

### Getting Started

* **ネイティブアプリ**は、様々なデバイスの機能にアクセス可能である一方、アプリそのものをユーザにリーチしづらい。

* **従来のWebアプリ**は、アプリそのものをユーザーにリーチしやすい一方、デバイスの機能へのアクセスにはかなりの制限がある。

* **PWA**なら、どちらのメリットも手に入れることができる。

 * PWAの特徴としては、Cachingを利用したオフライン対応、モバイルライクなWeb Push、ホームアイコンへの追加等がある。もちろん、デバイス依存のAPIも使える。


### Understanding the App Manifest

アプリケーションの情報を`manifest.json`として設定する必要がある。

| key           | description    |
|---------------|----------------|
| name                 | スプラッシュ画面に表示されるアプリ名    |
| short_name           | ホーム画面のアイコン下に表示されるアプリ名     |
| description          | アプリの説明     |
| start_url            | ホーム画面のアイコンをクリックした際、初期表示されるページ    |
| scope                | PWAを適用する範囲|
| display              | 表示モードの指定     |
| background_color     | スプラッシュ画面等の背景色       |
| theme_color          | スイッチャーのナビゲーション背景色等   |
| dir          | テキストの書字方向   |
| lang          | 使用言語   |
| orientation          | デフォルトの向き。強制力を持たせるプロパティもある   |
| icons          | アプリのアイコン情報（src,type,size）を指定する   |



```json
{
	"name": "Sweaty - Activity Tracker",
	"short_name": "Sweaty",
	"description": "Keep running until you're super sweaty!",
	"start_url": "./index.html" ,
	"scope": ".",
	"display": "standalone",
	"background_color": "#fff",
	"theme_color": "#3F51B5",
	"dir": "ltr",
	"orientation": "portrait-primary",
	"icons": [{
		"src": "/src/imags/icon/app-icon-48x48.png",
		"type": "image/png",
		"sizes": "48x48"
	},{
		"src": "/src/imags/icon/app-icon-96x96.png",
		"type": "image/png",
		"sizes": "96x96"
	}],
}
```

### The Service Workers

JavaScriptはシングルスレッドを前提にした言語であるが、Service Workerは**別スレッドで動作する。**
ページと外部の通信に割り込む機能があり、**プログラマブルなProxy**として動作する。
また、**イベント駆動型のWorker**であり、HTMLページから切り離されており、タブ・ブラウザを閉じた後でも動作し続ける。
※ `https` もしくは `localhost` 上でしか動作しない。

ライフサイクルについては複雑で、動画のみでは理解しづらい部分があった。
したがって、[公式ドキュメント](https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle?hl=ja)を並行して読んだ。


### Service Workers - Caching / Service Workers - Advanced Caching

`Cache API`の戦略的利用のためのセクション。
後の`Workbox`で登場する[`workbox.strategies.**`]をスクラッチで書く。（[strategies](https://developers.google.com/web/tools/workbox/modules/workbox-strategies
)）

Promiseや条件分岐が多発するので、「これを毎度のこと記述するのは辛いな〜」という印象だった。
一方で、かなり丁寧に説明してくれるので、このコースで最も勉強になるセクションだった。


### IndexedDB and Dynamic Data

ブラウザ内部の`Key-Value`なDatabase。
`LocalStorage`の場合は、文字列のみしか保存できないため、JSONを保存する場合はstringifyする必要があったが、`IndexedDB`はJSON形式で保存できる。
また、大容量であり、ファイルをBlob形式で保存することも可能。
さらに、`LocalStorage`は同期型だが、`IndexedDB`は非同期型。したがって、ファイルサイズが大きい動画等をローディング画面等の間に読み込むことが可能になる。

ちなみに、このコースでは、ユーザーの投稿データを`IndexedDB`にJSON形式で格納していた。


### Background Sync

ネットワークがオフラインの際に、ユーザーが投稿した場合、通常のアプリケーションならリクエストに失敗する。
`Background Sync`を利用すれば、ネットワークに再接続された際に、再度リクエストを送信することが可能。
当たり前ではあるが、Web Application側で、`sync.register`する必要がある。


### Web Push Notifications

PWAの知見が少ない方でも、この機能についてはご存知の方が多い。
一方で、`Push Server`やら`Permission`等を考慮する必要があり、実装コストは高そうだった。
本件の詳しい内容は、[[改訂版] Web Pushでブラウザにプッシュ通知を送ってみる](https://qiita.com/tomoyukilabs/items/2ae4a0f708a1af75f13e)が詳しいので、割愛する。


## 所感

**PWAでできること**は様々な記事で紹介されているので理解が容易い。また、ドキュメントも充実しているため、不明点の検索・理解も容易い。
しかし、プロジェクトベース、コードベースで学べるような記事がないため、初めの一歩を踏み出しづらかった。

そのような点では、今回のコースは非常に実りがありました。
基礎の理解を終えた上で、`Workbox`等のライブラリにも手を出してみたいと思います。