プログレッシブWebアプリコンプリートガイド

以下は、[THE COMPLETE GUIDE TO PROGRESSIVE WEB APPS](https://flaviocopes.com/what-is-a-progressive-web-app/)の日本語訳です。

# THE COMPLETE GUIDE TO PROGRESSIVE WEB APPS

Progressive Web Apps (PWA)は、モバイルアプリ開発の最新トレンドで、2018年初頭ではAndroid端末にだけ対応しています。

> WebKitはSafariとモバイルSafariの技術を元に、最近(2017年8月)Service Workerをブラウザに導入する作業を開始したと発表しました。
> これは要するに、遅かれ早かれiOS端末にも搭載されるということを意味するので、Appleが決心しさえすればiPhoneやiPadでもPWAを使用できるようになるということです。

PWAは画期的な新技術というわけではなく、Webベースのアプリケーションを作成するための一連のテクノロジーを識別する、新しい用語です。

## What is a Progressive Web App

PWAは、端末が対応しているなら、オフライン閲覧、PUSH通知、ネイティブアプリとほぼ同等の外観と速度、リソースのローカルキャッシュなどの追加機能を提供できるWebアプリのことです。

このテクニックは元々2015年にGoogleで開発されたもので、開発者とユーザの双方に多くの利点をもたらすことが証明されています。

開発者は、ネイティブアプリの開発よりずっと簡単で安価に、Web技術だけを用いてほぼネイティブアプリと同等のアプリケーションを構築することができます。
クロスプラットフォームのアプリを構築・保守していく場合は特にそうです。

アプリストアにアプリを公開しても、その99.99%は存在に気付かれることすらない昨今、Google検索から来るだけでインストールできるPWAはインストールの機会を増やすことができます。

PWAは、モバイルに最適化されただけの通常のウェブサイトよりも、モバイル体験をはるかに楽しくしてくれる技術によって開発されたものです。
PWAは、ネイティブアプリのように以下のような機能を提供します。

・オフライン機能
・高速なローディング
・セキュリティ
・PUSH通知
・URL欄を出さず全画面表示ができる

モバイル端末(執筆現時点ではAndroidだけだが、技術的にはそれだけに限定されていない)でサイトを訪れたとき、ホームスクリーンにアプリを追加するように通知を出すこともできます。

まずはPWAの定義をはっきりさせましょう。
Progressive Web Appは混乱を招きやすい定義ですが、ここではWeb WorkerやWeb App Manifestなど最新のブラウザ機能を活用したWebアプリケーションと定義します。
モバイル端末は、ただのWebアプリを第一級のアプリにアップグレードしてくれます。

## Progressive Web Apps alternatives

PWAは、他のモバイル閲覧技術と比較してどのような違いがあるでしょうか。
それぞれの長所と短所を調べて、PWAがどのような場合に適しているかを見てみましょう。

### Native Mobile Apps

ネイティブアプリは、モバイルアプリを構築する最もわかりやすい方法です。
iOSではObjective-CもしくはSwift、AndroidではJavaかKotlin、そしてWindowsPhoneではC#で開発します。

各プラットフォームはそれぞれ独自のUIとUXの規則が有り、プラットフォーム毎にユーザの期待したとおりのエクスペリエンスを提供します。
アプリはアプリストアを通して配布することができます。

ネイティブアプリ最大の問題点は、クロスプラットフォーム開発にあります。
プラットフォーム毎に全く異なる開発方法、ベストプラクティスを学んで知識を保たなければなりません。
小さなチームやソロ開発者であればさらに大変です。
テクノロジーの学習だけではなく、開発環境、ライブラリ、異なるワークフローの管理などに多くの時間を費やさなければならないでしょう。
(例えば、iCloudはiOSでのみ動作し、Android版は存在しない、など)

### Hybrid Apps

ハイブリッドアプリは、Webテクノロジーを使って開発され、各プラットフォームのアプリストアで配布されます。
アプリケーションを、アプリストアに適合するアプリにパッケージングする、フレームワークやその他の何かが存在します。

Phonegap、Xamarin、Ionic Frameworkあたりが有名で、他にも多くのプラットフォームが存在します。
これらで開発されたアプリの画面は基本的にWebViewで、つまりは本質的にローカルなWebサイトです。

ハイブリッドアプリの特徴は`write once, run anywhere`であり、同一のソースから各プラットフォームに対応したコードがビルドされます。
開発はJavaScript、HTMLそしてCSSで行われ、(マイク、カメラ、ネットワーク、GPS等)端末のネイティブ機能はJavaScript APIを通じて使用可能です。

ハイブリッドアプリの悪い点は、ハイブリッドアプリは開発の共通化のためにプラットフォーム固有の設計ガイドラインを無視しているため、うまいこと調整してアプリを作らないと、プラットフォームとして適切ではない挙動をするアプリができあがってしまうことです。

また、複雑な画面構成を擁するアプリはパフォーマンスが低下することがあります。

### Apps built with React Native

React Nativeは、JavaScript APIを用いてモバイル端末のネイティブ機能にアクセスしますが、WebView内にWebサイトを埋め込むのではなく、うまいことネイティブアプリ化しています。

ハイブリッドアプリと異なる点は、`learn once, write anywhere`がモットーであり、一度学習すれば同じ言語で各プラットフォーム毎のアプリを書けるということです。
逆に言うと、各プラットフォーム毎に完全に別のアプリを作成しなければならないということです。

パフォーマンスはネイティブアプリに匹敵します。
なぜなら、React Nativeで作成するのは本質的にネイティブアプリだからです。

## Progressive Web Apps features

前段落では、PWAの主なライバルたちを見てきました。
では、PWAは彼らと比較してどのあたりが異なるのでしょうか。

> Remember, currently Progressive Web Apps are Android-only

覚えておいてくれ、今のところPWAはAndroidしか対応してない

### Features

PWAは、前述のアプリとは完全に異なる点がひとつあります。
アプリストアで配布するものではない、ということです。

ここはとても大きな利点です。
アプリストアで真っ先に紹介される立場になれるような幸運を持っているのであればアプリストアは有益ですが、さもなければ貴方のアプリは0.001%の層にしか届きません。

PWAには、検索エンジンから到達することが可能です。
ユーザがPWA対応サイトにアクセスすると、ブラウザはホーム画面にアプリケーションをインストールするかどうかを尋ねます。
通常のSEOと同じ手法でPWAに集客することが可能になります。

アプリストアを使わないということは、アプリの公開にAppleやGoogleの承認を得る必要が無いということです。
iOSの厄介で面倒な承認プロセスを経ることなく、必要なときに即座にアップデートをリリースすることが可能です。

PWAは基本的にHTML5の機能をフルに使ったレスポンシブWebサイトで、重要な機能を実現するために導入された最新の技術が存在します。
HTML5モバイルアプリを作れと伝えられた開発者は、初代iPhoneにネイティブアプリを公開する機能が無かったことを思い出したことでしょう。
当時は技術的に準備ができておらず、ホームスクリーンにインストールすることができませんでした。

PWAはオフラインで稼働します。
Service workerがバックグラウンドで最新の情報をダウンロードし、PUSH通知することで、再訪問させる可能性を提供します。

さらにユーザは、アプリをシェアしたいときはURLを教えるだけでそれが可能になります。

### Benefits

開発者とユーザは、どうしてPWAを注視していく必要がありますか？

・PWAは軽量です。200メガバイト以上のネイティブアプリが溢れている昨今、PWAはわずか数キロバイトでも構築できます。
・プラットフォーム依存のネイティブコードはありません。
・ユーザの導入コストの軽減(Webサイトにアクセスするよりも、アプリをインストールしてもらうための敷居は遙かに高い)
・更新プログラムのリリースにかかる労力が大幅に軽減される。
・通常のアプリよりも、深い階層にアクセスしやすい。

### Core concepts

PWAのコンセプトは以下のとおりです。

・Responsive：UIは画面サイズに最適化される。
・App-like feel：一見Webサイトではなく、ほとんどネイティブアプリのように感じられる。
・Offline support：device storageを利用して、オフラインでも稼働する。
・Installable：端末のブラウザから、ユーザにインストールしてもよいか尋ねる。
・Re-engaging：PUSH通知により、ユーザがアプリを再訪することを助ける。
・Discoverable：サーチエンジンとSEO最適化により、アプリストアよりも多くのユーザに発見される可能性が高まる。
・Fresh：アプリ自身とコンテンツをオンライン時に更新することができる。
・Safe：HTTPSで安全。
・Progressive：古いデバイスでも、インストールできないなど機能は少ないながらも動作する。
・Linkable：URLで簡単にポイント可能。

## Service Workers

PWAの定義のひとつは、オフラインで動作する必要があることです。

Webアプリをオフラインで動かすことができるのはService Workerがあるからで、つまりService WorkerはPWAにとって必須の機能であるということです。

> 警告：Service Workerをサポートしているのは、現在Chrome、Firefox、Operaだけです。
> サポートについては[http://caniuse.com/#feat=serviceworkers](http://caniuse.com/#feat=serviceworkers)を参照してください。
> ヒント：Service WorkerとWeb Workerを混同しないでください。両者は全くの別物です。

Service Workerは、Webアプリとネットワークを仲介するJavaScriptファイルです。
キャッシュを提供し、レンダリング速度を高速化し、ユーザエクスペリエンスを向上させます。

セキュリティ上の理由から、Service WorkerはHTTPSでしか利用できません。
これが、PWAはHTTPS経由で提供しなければならない理由のひとつです。

Service Workerは、ユーザが初めてWebサイトを訪れたときには動作しません。
初回訪問時にはWeb Workerがインストールされ、その後サイト内の別ページを訪問した際に、初めてService Workerが起動します。

> Service Workerの[ガイド](https://flaviocopes.com/service-workers/)を参照してください。

## The App Manifest

App Manifestは、PWAに関する設定を記載したJSONファイルです。
Webサイトの全ページのヘッダにApp Manifestへのリンクを追加しましょう。

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

このファイルは、端末に以下の情報を提供します。

・アプリ名と短縮名
・アイコンのファイル位置とサイズ
・開始URL、ドメインからの相対URL
・デフォルトの向き
・スプラッシュ画面

### Example

```json
{
  "name": "The Weather App",
  "short_name": "Weather",
  "description": "Progressive Web App Example",
  "icons": [{
    "src": "images/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    }, {
      "src": "images/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    }, {
      "src": "images/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    }, {
      "src": "images/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }, {
      "src": "images/icons/icon-256x256.png",
      "sizes": "256x256",
      "type": "image/png"
    }],
  "start_url": "/index.html?utm_source=app_manifest",
  "orientation": "portrait",
  "display": "standalone",
  "background_color": "#3E4EB8",
  "theme_color": "#2F3BA2"
}
```

[App Manifest](https://www.w3.org/TR/appmanifest/)は2018/02/05現在、W3Cの[作業草案](https://www.kanzaki.com/w3c/process.html#wd)段階です。

## The App Shell

App Shellはテクノロジーではなくデザインコンセプトです。
最初にローディングやレンダリングを行う際に、ネイティブアプリのような印象を与えます。
読み込みに長時間かかるアプリをスプラッシュ画面などで誤魔化すためのもので、Apple HIGと同じようなものです。

### Caching

App Shellはアプリのコンテンツとは別にキャッシュされていて、キャッシュからのデータの取り出しと画面表示にはほとんど時間がかからないように設計されています。
App Shellの詳細については[こちら](https://developers.google.com/web/updates/2015/11/app-shell)を参照してください。

## 奥付

2018/01/25 Flavio Copes著。
React、Rudex、PWA、ES6、ES7、ES8、Webpack、GraphQL、Babel、ServiceWorker、Fetch、PUSH通知等についてまとめた[Modern Web Development](https://gumroad.com/l/FKbd?wanted=true)って本を書いたよ！


# 感想

勝手にホームアイコンを作るし余計なPUSH通知はするしと設計意図が奸邪で個人的に大嫌いなので普及しないでください。
ホームアイコンとPUSH通知を一切合切未来永劫完全拒否する設定があるなら普及してもいいぞ。

さすがにコンプリートは言い過ぎじゃねという気がしないでもない。
Benefitの`Much more support for deep links than regular app-store apps`がよくわからなかった。