Slide 1

Slide 1 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 1 「いこレポ」での Workbox導入事例 アクトインディ株式会社 森下泰光

Slide 2

Slide 2 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 自己紹介 森下 泰光 ● アクトインディ所属 ● Webエンジニア ○ インフラからフロントエンドまで色々やってます ● Alexaスキルとかもやってます

Slide 3

Slide 3 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. アクトインディについて メインサービス「いこーよ」は Webメディアとして多くの子育て中のご 家族にご利用いただいています。 iko-yo.net 2019/07 PV:6,000万/月 UB:1,000万

Slide 4

Slide 4 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. いこレポについて いこーよの姉妹サイト「いこレポ」はお出 かけ記事を提供するメディアサイトです。 report.iko-yo.net 2019/07 PV:380万/月 UB:83万/月

Slide 5

Slide 5 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Railsアプリケーションに Workboxを導入する話 と Add To Home Screenをカスタムする話 をします

Slide 6

Slide 6 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Webエンジニアの方?

Slide 7

Slide 7 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Railsで開発している方?

Slide 8

Slide 8 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 「Workbox使ってるよ」って方?

Slide 9

Slide 9 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 2017年7月: サービス開始 2018年7月: 1周年で200万PV/月超え 2019年8月: 約500万PV/月

Slide 10

Slide 10 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. PWA化の動機 順調にPVを伸ばし成長しているが... トラフィックはほとんど検索流入 しかも、ほとんど新規ユーザ。 リピーター増やしたい…。 ホーム画面にアイコン作ってもらえれば増やせるかも。 アイコン追加を促す仕組みがあったはず! Add to Home Screen(A2HS)を使いたい!

Slide 11

Slide 11 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Add to Home Screenとは? 条件を満たすWebサイトに アクセスした際に 「ホーム画面に追加」しませんか? とブラウザが促してくれる仕組み。 実装例:amp.dev これ

Slide 12

Slide 12 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Add to Home Screenの表示条件 ● すでにインストールされていないこと ● prefer_related_applications: false であること ● マニフェストに次の含むこと ○ short_name または name ○ 192px と 512px のicons ○ start_url ○ display が fullscreen, standalone, minimal-uiのいずれか ● HTTPS ● ServiceWorker が登録されていること ● ServiceWorkerでfetchイベントハンドラを実装していること https://developers.google.com/web/fundamentals/app-install-banners/ Chromeでの話です。

Slide 13

Slide 13 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. いこレポはすでにほとんど満たしていた ✅ すでにインストールされていないこと ✅ prefer_related_applications: false であること ✅ マニフェストに次の含むこと ○ short_name または name ○ 192px と 512px のicons ○ start_url ○ display が fullscreen, standalone, minimal-uiのいずれか ✅ HTTPS ✅ ServiceWorker が登録されていること ❌ ServiceWorkerでfetchイベントハンドラを実装していること 実は初期開発で実装していたものの、最後の条件が追加され動かなくなっていた

Slide 14

Slide 14 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. fetch イベントハンドラって? ServiceWorkerの主な用途であるキャッシュ その際、ServiceWorkerはサーバへの通信を横取りしてキャッシュがあれば それを返し、通信はしないように実装する。 これを実現するのが、Fetch API。 ブラウザの通信を横取りするためにはfetchイベントハンドラを実装する キャッシュを実装すればA2HSが有効になる!

Slide 15

Slide 15 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. キャッシュを自前で実装するのはなかなか大変 ServiceWorkerを自前で実装するのは面倒。 しかもキャッシュを実装するのは結構難しい ● すでにキャッシュされている場合とされていない場合 ● キャッシュとサーバからの取得どっちを優先するか ● 古くなったキャッシュの更新 ● etc 実装するからにはちゃんとしたい(ちょっとでも速くなったら嬉しい) でも、キャッシュするということ自体がモチベーションではない 楽したい

Slide 16

Slide 16 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxとは ● Google製のServiceWorkerサポートライブラリ ● 主にオフライン対応をサポート ○ precache ○ runtime cache ● Webpack Pluginがある これを使います

Slide 17

Slide 17 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ここから RailsにWorkboxで キャッシュを実現する話です

Slide 18

Slide 18 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. いこレポのソフトウェアスタック しっかりRails Wayに乗っかったRailsアプリケーション ● Ruby 2.6.3 ● Rails 5.2.3 ○ webpacker 4.0.7 ■ Webpack 4.32.2 ■ Babel 7.5.5 ■ workbox-webpack-plugin 4.3.1 ■ Vue.js 2.6.10

Slide 19

Slide 19 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. いこレポのJavascript・CSS事情 Webpackerを導入しているが、 Assets Pipelineも使っている というか、Assets Pipelineがメイン Assets Pipeline ● ユーザ向けページで使うJS、CSS等のみ扱う Webpacker ● <管理画面用Dir>/ 管理画面で使うJS、CSS ● front/ ユーザ向けページで使うJS,CSS Assets Pipelineで ビルドされるファイル ユーザ向けページで 使われるもののみ WebPackerで ビルドされるファイル ユーザ向けページで 使うものと 管理画面で使うものが ある

Slide 20

Slide 20 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. キャッシュの方針 ①静的なアセットは基本プリキャッシュ ● assets/**/* ● javascript/packs/front/**/* ②ただし、PC向けアセット、管理画面用アセット はキャッシュしたくない ● assets/**/pc/**/* ● javascript/packs/<管理画面用>/**/* ③記事で使われている画像は ランタイムキャッシュでキャッシュしたい キャッシュしたい キャッシュしたくない

Slide 21

Slide 21 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. workbox-webpack-pluginの動作 ● WebPackのプラグインとして設定する ● ビルドするとServiceWorkerを実装したJSを生成する ● プリキャッシュ ○ WebPackでビルドした出力はデフォルトでキャッシュする ■ キャッシュ対象は precache-manifest.****.js に記載される ○ 設定すればWebPack無関係なファイルもキャッシュできる ■ キャッシュ対象は sw.jsに記載される ● ランタイムキャッシュ ○ パターンを設定すればキャッシュされるようになる

Slide 22

Slide 22 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workbox視点でキャッシュの方針を見ると 1. Webpackでビルドするファイルでプリキャッシュしたくないものがある 2. Webpackに無関係なファイルでプリキャッシュしたいものがある 3. ランタイムキャッシュも使いたい

Slide 23

Slide 23 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定① 1. Webpackでビルドするファイルでプリキャッシュしたくないものがある 関連する設定項目 一部をキャッシュから除外したいので exclude が使えそう 設定項目 説明 include 正規表現のリストを設定する。 マッチしたファイルをプリキャッシュに含める 例)include: [/\.html$/, /\.js$/] exclude 正規表現のリストを設定する。 マッチしたファイルをプリキャッシュから除外する 例)exclude: [/\.jpg$/, /\.png$/]

Slide 24

Slide 24 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定② 2. Webpackに無関係なファイルでプリキャッシュしたいものがある 関連する設定項目 設定項目 説明 globDirectory workbox無関係だけどプリキャッシュしたいファイルのベースディレクトリを指定 する 例)globDirectory: '.' globPatterns globDirectoryの中でプリキャッシュするファイルのパターンを指定する 例)globPatterns: ['dist/*.{js,png,html,css}'] globIgnores プリキャッシュから除外したいファイルのパターンを指定する 例)globIgnores: ['**/ignored.html'] modifyUrlPrefix Webpack無関係なプリキャッシュファイルのURLを書き換える CDNのURLに変更する等に利用する 例)modifyURLPrefix: { '/dist': '' }

Slide 25

Slide 25 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定③ 3. ランタイムキャッシュも使いたい 関連する設定項目 設定項目 説明 runtimeCaching 下記の設定を含むオブジェクトのリスト urlPattern キャッシュするURLパターンを正規表現やglobパターンで指定する handler 'NetworkFirst'や'CacheFirsdt'などのキャッシュ戦略を指定する options 有効期限やキャッシュするファイル数、などを設定する

Slide 26

Slide 26 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ● インストール ● 設定 ○ workboxの設定だけのファイルを作成 ○ 上記を config/webpack/production.js で読込(後述) Workboxのインストール

Slide 27

Slide 27 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. キャッシュの方針 ①静的なアセットは基本プリキャッシュ ● assets/**/* ● javascript/packs/front/**/* ②ただし、PC向けアセット、管理画面用アセット はキャッシュしたくない ● assets/**/pc/**/* ● javascript/packs/<管理画面用>/**/* ③記事で使われている画像は ランタイムキャッシュでキャッシュしたい キャッシュしたい キャッシュしたくない

Slide 28

Slide 28 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定 設定のポイント 1. modifyUrlPrefix でCDNからプリ キャッシュファイルを取るように 設定 2. exclude で管理画面用のファイル をプリキャッシュから除外 3. Webpack無関係ファイルのプリ キャッシュ 4. ランタイムキャッシュも設定 1 2 3 4

Slide 29

Slide 29 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定 1. modifyUrlPrefix でCDNからプリキャッシュファイルを取るように設定 環境変数 AWS_S3_HOST_ALIASが定義されていれば、そのホストから取得するように設定 ただし、この設定の影響範囲はWebpack無関係なファイルのみ Webpackで生成されるファイルには適用されない(対処方法は後述)

Slide 30

Slide 30 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定 2. exclude で管理画面用のファイルをプリキャッシュから除外 WorkboxはデフォルトでWebpackでビルドされる出力ファイルをすべてプリキャッシュする exclude は そこから除外するファイルを指定する設定 正規表現にマッチしたファイルを除外する

Slide 31

Slide 31 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定 3. Webpack無関係ファイルのプリキャッシュ キャッシュしたくないパスを設定 プリキャッシュに入れる拡張子を指定 public以下をプリキャッシュ

Slide 32

Slide 32 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Workboxの設定 5. ランタイムキャッシュも設定 ブラウザが使える容量を超えたら削除

Slide 33

Slide 33 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Rails+Webpackerで使う場合 ● Workboxの設定は次の様に読み込む config/webpack/production.js publicPath の設定 公開パスを設定する。CDNから取得するように設定 Workboxの設定の読み込み

Slide 34

Slide 34 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Rails+Webpackerでのビルド ● rake webpacker:compile で webpak build が実行される ● 実際には rake assets:precompile を実行するだけ。 ○ assets/ 以下のファイルのビルドのあと webpacker:compile も実行される

Slide 35

Slide 35 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 以上でRails+Webpackerにおける Workboxによる キャッシュ設定は完了

Slide 36

Slide 36 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 結果

Slide 37

Slide 37 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ここからが本題 Android Chromeにおける A2HSの話

Slide 38

Slide 38 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 条件は満した ✅ すでにインストールされていないこと ✅ prefer_related_applications: false であること ✅ マニフェストに次の含むこと ○ short_name または name ○ 192px と 512px のicons ○ start_url ○ display が fullscreen, standalone, minimal-uiのいずれか ✅ HTTPS ✅ ServiceWorker が登録されていること ✅ ServiceWorkerでfetchイベントハンドラを実装していること

Slide 39

Slide 39 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ● いこレポにアクセスすると次のような ミニインフォバーが画面下部に表示される デフォルトのA2HS 分かりづらいので改善したい

Slide 40

Slide 40 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. いこレポで実装したA2HS

Slide 41

Slide 41 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 操作の流れ 条件満たす キャンセル ポップアップ表示 終了 ボタンクリック プロンプト表示 キャンセル 終了 追 加

Slide 42

Slide 42 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. beforeinstallpromptイベントハンドラを実装する ● ミニインフォバーが表示されるタイミングで beforeinstallpromptイベントが発火する ● beforeinstallpromptをキャプチャして カスタムポップアップを表示する どうやってカスタマイズするか?

Slide 43

Slide 43 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 最もシンプルな実装 いずれかをクリックするまで ブロック

Slide 44

Slide 44 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 問題点:キャンセルできない ● キャンセルしてもキャンセルしても beforeinstallpromptイベントが発火する → ポップアップ表示がアクセスのたびに表示 ● ホームアイコンを追加すればもう表示されない → その前にユーザを怒らせてしまう Cookieを使って一定期間表示しないようにした

Slide 45

Slide 45 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. Cookieをセット/確認する関数 これらの関数でCookieをセット、有無を確認する Cookieがなければポップアップを表示し、あれば何もしない

Slide 46

Slide 46 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. キヤンセル できるように どっちがクリックされたかを判定

Slide 47

Slide 47 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 課題:効果測定 ● 次を測りたい ○ どれくらいのユーザがホームアイコンを追加してくれるのか ○ あるいは追加してくれないのか Google Analyticsにイベントを送って計測

Slide 48

Slide 48 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 最終的なコード

Slide 49

Slide 49 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. イベント送信箇所 条件満たす キャンセル ポップアップ表示 終了 ボタンクリック プロンプト表示 キャンセル 終了 追 加

Slide 50

Slide 50 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 計測結果 イベント 回数 open 150万 popup-cancel 140万 popup-ok 12,000 dismissed 7800 installed 3800 設置してから記録されたイベント数は次の通り

Slide 51

Slide 51 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. こういうことです 条件満たす キャンセル ポップアップ表示 終了 ボタンクリック プロンプト表示 キャンセル 終了 追 加 150万 140万 12,000 7800 3800 登録率 0.25%

Slide 52

Slide 52 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ホームアイコン追加してもらうのは 厳しい

Slide 53

Slide 53 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. まとめ ● WorkboxによってServiceWorkerのキャッシュは 比較的容易に実装できる ● Webpackを利用しているのなら webpack plugin を利用すると楽 ● Webpackで出力しないファイルや CDNから配信するファイルのキャッシュも可能 ● ホームアイコンを作ってもらうのはなかなか険しい

Slide 54

Slide 54 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. ありがとうございました

Slide 55

Slide 55 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 参考 ● Workbox https://developers.google.com/web/tools/workbox/ ● Workbox webpack Plugins https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#configuration ● Add to Home Screen https://developers.google.com/web/fundamentals/app-install-banners/ ● The mini-info bar https://developers.google.com/web/fundamentals/app-install-banners/#mini-info-bar ● What is an opaque response? https://blog.fullstacktraining.com/what-is-an-opaque-response/

Slide 56

Slide 56 text

Copyright (C) 2019 ActIndi, Inc. All Rights Reserved. 本日の発表の元になったブログエントリ ● workbox を導入してServiceWorkerによるキャッシュを実装した話 https://tech.actindi.net/2018/10/05/083913 ● Workboxのプリキャッシュの設定でハマった https://tech.actindi.net/2019/08/02/090212