Google Developer Summit 2016 (Day2)


# Location
* 2016/04/26 13：30-18：30
* コクヨホール
* 前日のAndroidの会よりは空席があったがほぼ満員
* 初日（Android編）はこちら：http://qiita.com/doc0s/items/03fdf24e75ebbf7393ed
* サマリ:
**Web技術を使って、巨大なユーザベース、高いパフォーマンス、Home画面という一等地からの起動、端末へのPush通知といったMobileの素晴らしい点を取り込みつつ、Webならではの、インストール不要・自動アップデート可能というアドバンテージも活かした次世代のWebAppを作っていこう、そのための道具は揃っている。Securityとか、誰にいつどんな通知を出すかなんてこともとっても重要だよ。**

# Introduction to Progressive Web Apps
**Robert Nymanさん**
キーノート的な内容。

## Web の進歩の歴史
* XMLHTTP（Outlook web access）、Gmail、Ajax、Mobile(iPhone)、ServiceWorker
* Chromeのユーザが10億人突破

## Webの現在
* Web & Native
    * NativeのトラフィックはWebの半分
    * MobileでのWeb利用時間はBrowserの10倍
    * 一般的に言って、Appstore -> Install -> Signup -> ... という各ステップで20%ずつくらいユーザ離脱する
    * MobileくらいEngagingでダウンロード&インストールが必要ないアプリをつくるには？
        * Linkable
			* Web=だれがどこでホストしてようがInternetにつながったらOK
	    * Indexable
    	    * だれでも（金持ちも貧乏人も）同じ情報にアクセスできる
    	* Composable
        	* モジュールを組み合わせる
    	* Ephemeral(はかない **注釈：よくわかりませんでした**)
    * Why native?
         * Performance
         * Offline access
         * Periodic background processing
         * Noifications
         * Sensors
         * OS-specific features

* Progressive webapp
    * reliable, fast, engaging...
        * browser上でNativeアプリのように振る舞うWebApp
        * **注釈：**ChromeOS、FirefoxOSで目指してたやつでは？
            * いつもデバイスへの貧弱なアクセス、パフォーマンスの悪さといった理由で使えなかった

* Web app manifest

```index.html
...
<meta name="theme-color" content="#242424">
<link rel="manifest" href="/manifest.json">
...

```

```manifest.json
{
    "short_name": "Air brabra",
    "name": "Air brabra",
    "start_url": "/",
    "display": "standalone",
    "orientation": "portrait",
    "icons": [
        {
          "src": "launcher-icon-2x.png",
          "sizes": "96x96",
          "type": "image/png"
        },
        {
          "src": "launcher-icon-3x.png",
          "sizes": "144x144",
          "type": "image/png"
        },
        {
          "src": "launcher-icon-4x.png",
          "sizes": "192x192",
          "type": "image/png"
        }
    ]
}
```

* Home launcher
    * 一定の期間に2回使われたアプリは ホームに追加するようAndroid Chromeが促してくれる
* Web push notifications
    * ページが閉じていてもNotificationを送ることができる

* PWA can work accross browsers（ほんとかな？）
* 1分ー3.5分の利用を3回行った人は1週間以内に40%再訪問してくれるそう


# Security for all    
**田中 洋一郎さん**

## HTTPS大事
* SSL/TLSなしでWebアプリ作ったらISPとか他の外部サービスが広告とかなんでも入れてしまえる→Webを書き換えられてしまう
* HTTPSが必須要件となる機能には以下のものがある
    * ServiceWorker
        * Offline
        * Push
        * BackgroundSync
        * 今後追加される機能すべて
    * Add to homeスクリーンをAndroidChromeがサジェストしてくれるにはHTTPS必須
    * HTTP2
    * Brotli
    * getUserMedia(), Geolocation→これらもHTTPSでないといけないようになってきている

## HTTPS大変
* HTTPS化しようとするだけでもうまくできなかった。→鍵マークが出なかったり、やっと出ても弱いアルゴリズムが使われていて脆弱性が検知されたり
* セキュリティの技術は日進月歩なのでぐぐっても古い情報を掴まされる

## 面倒なHTTPS対応をどうやって実現するか
* Deploy先をPaasにしましょう
    * GCP、Firebase、AWS、、、
    * セキュリティアップデートにも追随してくれる

* CloudFlare
    * 自分のサーバとInternetの間に入っていい感じにセキュアにする
    * CloudFlareと自分のサーバの間は自己証明書でもよい

* Lets encrypt
    * フリーのSSL証明書を提供
    * 証明書の期限が短い→コマンドラインツールで自動アップデートしないといけないようにしている
    * bit.ly/ssl-config-gen
        * 自分のサーバに設定するときのConfigファイルを生成してくれる
        * その時点でもっとも安全と思われる設定をしてくれる
    * bit.ly/ssl-labs
        * sslを設定した時にそのWebサイトの安全性を客観的に検証してくれる


* **注釈:**話を聞いていて2年前ののGoogleのHTTPS Everywhereのビデオを思い出した。重要な内容なので重なる部分が多い。https://www.youtube.com/watch?v=cBhZ6S0PFCY

# Instant loading
**矢倉 眞隆さん**

## Instant loadingがなぜ重要か
* Web appはInstallが必要ない。さらにローカルキャッシュを使えればLoadingも必要ない。最初のセッションでも触れられたように1ステップあたり大体20%のユーザが離脱する。なので0.8*0.8=0.64で36%のドロップを防げる（**注釈:**乱暴な説明と感じた）
* Amazonによると、100msec読み込みが遅くなると1%利益が下がるとのこと


## WebAppをなるべく早くロード・起動するには
* Service workerを使うだけでは不十分
    * ネットワークから最初に読み込むのにかかる時間をどうやって速くするか
* まずはアセットを小さくする（html, js, css）
* 少しでもアセットを小さく
    * 画像リソースは可能な限り小さいものをデバイスごとに降らせる
        * 大は小を兼ねるということででかいサイズだけを置くのはだめ
    * 特定ブラウザ向けのコードはそのブラウザだけに降らせる
    * リソースのダウンロードする順番を制御
    * ローカルキャッシュを使って、アップデートのアップデートがあったファイルだけダウンロード
    * js、cssはminifyしかつ圧縮：60-80%
    * 画像にはwebPをなるべく使う：Jpegで30%、PNGで25%
* srcset、media queryの利用
    * 次の2つのサンプルのように書くと必要ないリソースはブラウザはダウンロードしない

```webpがあったら使ってなければimgタグのjpgを使うサンプル.
<picture>
    <source srcset="washing.webp">
    <source srcset="washing.jpg">
    <img src="washing.jpg">
</picture>
```


```media-queryを使って画面サイズごとに使うリソースを指定するサンプル.
<img sizes="(max-width: 30em) 100vw,
            (max-width: 50em) 50vw,
            calc(33vw - 100px)"
    srcset="swing-200.jpg 200w,
            swing-400.jpg 400w,
            swing-800.jpg 800w,
            swing-1600.jpg 1600w"
    src="swing-400.jpg" alt="Kettlebell Swing">
```


* JSの遅延ロード、非同期読み込み

```
<script>
<script defer>
<script async>
```

* CSSには非同期読み込みの仕組みがないのでJSのライブラリを使う。例えば...
    * github.com/filamentgroup/loadCSS
    * ページ全体に適用したらいけてない表示になるので使うところをちゃんと考える

* Regioning CSS、AssetへのID付与、CDN、HTTP2の利用、Concatenation, Sharding, Cookies、etc


# Offline first experiences
**北村 英志さん**

## Service workerについて
* ページとは別にスクリプトを動かせる
* ページが閉じていてもスクリプトを動かsれ
* ページからネットワークに

## Service workerの利用
* navigator.serviceWorker.register('/sw.js')
* Chrome developer toolでのServiceWorkerのデバッグが可能
* index.htmlの読み込み完了前でもデバッガでキャプチャできるようになった
* ブラウザがネットワークに投げようとしたリクエストをServiceWorkerが中継することができる

* localproxyとしてServiceWorkerが使える
    * ユースケース
        * カスタム404を返す
        * オフラインの時はカスタムのhtmlを返す
        * レスポンシブイメージローダー
        * レスポンスをキャッシュしてServiceWorkerが返す

* Application Cache
    * 使いづらいし問題がおおくて流行らなかった

* ServiceWorkerを使ってpre-cacheが可能
    * 色々書くことがあって大変だが以下を使えば簡単化可能
        * sw-precache（https://github.com/GoogleChrome/sw-precache）
        * リソースのURLリストを記述して宣言的にプリキャッシュできる。Gulp/GruntでビルドしてScriptを生成できる。自動的にバージョニング（ファイル名）。

* Dynamic dataの扱い
    * 例：天気予報のデータ等、頻繁に変わる構造化されたデータ
    * ネットワークに取りに行けたらネットワークに、できなければキャッシュを使う（ネットワークファースト）
    * これも便利なツールがある
        * sw-toolbox（https://github.com/GoogleChrome/sw-toolbox）
    * Indexed database
        * 構造化されているデータを保存する

* Service workerは全ブラウザで対応済みというわけではない
    * IE, Safariなどは非対応


# Make it installable and engaging    
**Paul Kinlanさん**

* AndroidではHomeにWebAppを置くには8ステップも必要だった
* App manifestの発明によりステップ数が激減した
* Androidでのmanifest.json内の値の使われ方
    * 追加しようとした時にでるPopupに"name"
    * 追加後のアイコン下のテキストに"short_name"
    * Splashスクリーン
        * 画面下部に"name"
        * "icons"のうちの最大サイズのものを中央に表示
        * "theme_color"は通知バー
        * "background_color"は背景
    * "display"の値
        * "standalone" -> full screenで起動
        * "window" -> URLバーのあるブラウザWindow付きで起動
            * URLBARやページヒストリーがあえて欲しかったら指定する。Facebookがこれに相当

* PWAで大切な3つのこと
    * Offline experience, Have a manifest, User is engaged
    * 何を以ってengagedとするかを厳密に定義 → 5分で2つの操作をしたうえで1週間以内に戻ってくる
        * Engageされたユーザ以外に通知を出すとSpamになるのでちゃんと定義するのが大事

* Add to homeを制御する方法：onbeforeinstallprompt

```制御してみるサンプル.
var deferredEvent;

window.addEventListener("beforeinstallprompt", 
  (e) => { 
    e.preventDefault();
    deferredEvent = e;#あとで再開するように覚えておく
    // show install button
  }
);

button.addEventListener("click", (e) => 
  deferredEvent.prompt();#クリックされた時にAdd to homeを実行
);
```

```InstallPromptが成功したか失敗したか.
var deferredEvent;

window.addEventListener("beforeinstallprompt", 
  (e) => 
    e.prompt().then((r) => r.userChoice)
              .then((c) => {
                 if(c.choice == "installed") {
                   // Success
                 } else {
                   // The user cancelled
                 }
              })
);
```

* InstallBannerのテスト
    * chrome dev toolから”Request app banner”という項目を選択することでInstallBannerを表示できる


* 参考情報
    * web fundamentals: https://goo.gl/UanrqB
    * sample: https://goo.gl/10gmcj
    * spec: https://w3c.github.io/manifest/


# Hey, look at me, I’m a notification 
**Pete LePageさん**

* Re-engagementがテーマのセッション
* Notificationでユーザをいらっとさせたら二度と来てくれないよ
* BeyondTheRackというショッピングサイトでNotificationを効果的につかったら、使用時間72%アップ、売上26%アップ、再訪問率50%アップとなったとのこと

* Notificationで大事な３つのこと
    * Timely
        * CalendarのReminderとか
    * Precise
        * 正確に、曖昧さをなくし、何なのかわかるように
    * Relevant
        * 望む人に望むものをちゃんと届けましょう
    * Offline

## Notification
* Chromeは今はGCMを使っているが、将来はWebPushAPIを使うようになる
* GCMにアプリを登録したうえで、gcm_sender_idをManifest.jsonに追加（Chrome/GCMでやる場合）

```
"gcm_sender_id": "fsjlkaafsafas…"
```

* Firefoxは上記は必要なくWebPushAPIに対応済み

* clientside
    * serviceworkerを使って、Subscription状態の取得、Registration、Unsubscribeを実装する
    * Subscription情報の中身
        * endpoint のURL
        * key:
            * auth
            * p256h

```現在のSubscribe状態をチェックするサンプル.
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/service-worker.js')
    .then(function(reg) {
      reg.pushManager.getSubscription()
        .then(function(sub) {
          console.log('Subscription Info', sub);
        });
    });
} else {
  console.log('Subscription Info', 'Not Supported');
}
```

```Subscribeを実行するサンプル.
function subscribe() {
  navigator.serviceWorker.getRegistration().then(function(reg) {
    reg.pushManager.subscribe({userVisibleOnly: true})
      .then(function(sub) {
        console.log('Update Server with End Point', sub);
      }).catch(function(error) {
        console.log('Unable to subscribe user', error);
      });
    });
}
```

```Unsubscribeを実行するサンプル.
function unsubscribe() {
  navigator.serviceWorker.getRegistration().then(function(reg) {
    reg.pushManager.getSubscription().then(function(sub) {
      if (sub) {
        sub.unsubscribe();
        console.log('Unsubscribe - user has been unsubscribed!');
      }
    });
  }).catch(function(error) {
    console.log('Error while trying to unsubscribe', error);
  });
}
```

* 通知を受信するかどうかの許可を求めるときにちゃんとなんのNotificationなのかを説明すること。よくわからない説明を書いてしまうとそこでDropしてしまう。
* 送るメッセージの暗号化はには、Web push encryption（github.com/GoogleChrome/web-push-encryption）がおすすめ

# Future of the web platform
**Sam Thorogoodさん**
基本的に他のセッションと同じく、Offline対応しManifestを使ってHomeにLauncherアイコンを置こうという話がメインなのでほぼ省略し、他とかぶっていないところだけ書く

* Santa Tracker
    * 12月にGoogleがWeb上で展開するサンタクロースを世界中からトラックするゲーム
    * 2015年、位置情報をユーザに提供してもらってユーザからサンタの距離を測ろうとした。あんまり位置情報提供許可してくれなかった。
    * GeoLocationAPIでIPから位置を引けるようにした
* Google+で実際にあった事例としてフルスクリーンのBlockingPopupで70%ドロップしたことがあったそう。通知はEngagedユーザに対して注意深く出すべき。
* LoadingをSpinner（ぐるぐる表示）でやるとユーザにストレスを与えるのでFacebookでは背景Blurを導入したところユーザはデータを今ローディングしているということを理解し、待ってくれたんだって（**注釈:**なぜ？？理由がよくわからなかった。）

* その他のキーワード： Imperative html, Document.onLine、Media streamAPI、etc


# SUUMO における Progressive Web Apps の活用事例   
**片山 雄介さん**

## SSL化
* LocalStorageのhttp https同期
    * 同一ドメインでもhttpとhttpsでLocalStorageは異なる
    * 結局サーバを開始、一旦アップし移行後に引き出すということをした
    * そもそもお気に入りなどの情報をLocalStorageのみでやったのが間違いではないのか
* 全リソースのURLの変更
* 移行期にコードレイヤーでのリダイレクト
* 非リンクのURLのhttpsへの変更
    * 今はhttp→https へのリダイレクト
* HSTS
    * Strict-Transport-Securityヘッダ応答を使って、一度HTTPS接続したら次回以降はHTTPSで接続

## PWA
* Add to Home(Web appのLauncherアイコンをホームに置く)
    * Conversion rateを18％上げた
* Offline cache
    * 更新の頻度の低い画面はOfflineキャッシュ化
    * PolymerのServiceWorker機能でローンシミュレーション機能を実装した。こういった機能もOfflineCache向き
* push notification
    * 新着物件の通知
    * Chrome50でやっとPayload対応
    * それまではpushが来たらサーバから新着情報をpullしていた


# Better mobile experience with AMP   
**山口 能迪さん**

## AMPの概要
* Accelerated Moblie Pages
* サイトの起動時間が３秒以上だと40%のユーザが断念してしまう
* 高速化は大事、でも静的なサイトでも最適化必要
* AMPが早い理由は、機能を限定、可能な限り遅延ロード、非同期読みこみ、レイアウトコストの低減、レンダリングの最適化
    * https://amphtml.wordpress.com/2015/12/16/why-amp-is-fast/

* AMPキャッシュは自動的にhttp2で通信される

## AMP対応方法
*  流れ
    1. AMP html作成
    1. Validatorでエラーが消えるまで修正
    1. Structured dataに間違いないか確認
    1. Canonicalpageからリンクをする

* 作成手順詳細
    * https://www.ampproject.org/docs/get_started/create_page.html

* ChromeCustomTabsとの組み合わせでさらに良いパフォーマンスが得られる
    * CustomTablsClient#warmup
    * CustomTablsSession#mayLaunchUrl

# 所感
* ServiceWorkerのデモ、InstallableWebAppのつくり方、NotificationによるReengagementの勘所、AMP（全く知らなかった）、WebPushAPIのサンプルなどの内容が有益だった