PWAとCache API #frontkansai

F7f43b56c430d12358a8581d9e331000?s=47 tiwu
November 02, 2019

PWAとCache API #frontkansai

FRONTEND CONFERENCE 2019 https://2019.kfug.jp/
で登壇した資料です

F7f43b56c430d12358a8581d9e331000?s=128

tiwu

November 02, 2019
Tweet

Transcript

  1. PWAとCache API Wataru Taguchi

  2. • 自己紹介 • PWA • Service Worker • Cache API

    • まとめ アジェンダ
  3. # Wataru Taguchi - GameWith Engineer - PWA, Web Components,

    AMP - パフォーマンスチューニングが好き - @tiwu_official - FF14, ストファイ5, Beer, Kyoto Animation 自己紹介
  4. None
  5. Progressive Web App PWA

  6. • 高速&高信頼性 • インストール可能 • モバイル&デスクトップ PWAの特徴 https://developers.google.com/web/fundamentals/codelabs/your-first-pwapp/?hl=ja

  7. • 高速 = インタラクティブな体験を提供するまで5秒以内 • 高速さは確実である必要がある ◦ ユーザーはインストールすることで高速な起動を期待する ◦ アプリのようにインストール後は必ず高速に起動すること

    高速&高信頼性
  8. • PWA はブラウザでも見れるが、インストールもできる • ブラウザのブックマークとは異なり、ネイティブアプリと同様にホーム画面に追加さ れる • スプラッシュスクリーン、アイコンなどでカスタマイズ可能 • アドレスバーなどのブラウザUIのない独立したアプリとして起動する

    • PWA をインストールするユーザーはネットワーク接続がどのような状態でも起動す ることを期待する • DEMO https://twitter.com/i/status/1100018179479224321 インストール可能
  9. • レスポンシブデザインによりモバイル&デスクトップで動作する • コードはプラットフォームによらずHTML、CSS、JavaScript モバイル&デスクトップ

  10. PWAにおける速度とは

  11. • 高速 = インタラクティブな体験を提供するまで5秒以内 • 高速さは確実である必要がある ◦ アプリのようにインストール後は必ず高速に起動すること ◦ ユーザーはインストールすることで高速な起動を期待する

    高速&高信頼性
  12. • PWA はブラウザでも見れるが、インストールもできる • ブラウザのブックマークとは異なり、ネイティブアプリと同様にホーム画面に追加さ れる • スプラッシュスクリーン、アイコンなどでカスタマイズ可能 • アドレスバーなどのブラウザUIのない独立したアプリとして起動する

    • PWA をインストールするユーザーはネットワーク接続がどのような状態でも起動す ることを期待する • DEMO https://twitter.com/i/status/1100018179479224321 インストール可能
  13. どのようなネットワークの状態でも 安定して高速であること PWAにおける速度とは

  14. • Wi-Fi • 4G,3G • 速度制限 • オフライン • etc...

    ネットワークの状態
  15. 安定した速度を出すために ネットワークからリソースを取得をしない

  16. 安定した速度を出すために Service Worker を利用し キャッシュされたデータを利用する

  17. ブラウザのバックグラウンドで実行されるスクリプト • プッシュ通知 • バックグラウンド同期 • オフライン対応 Service Worker

  18. • Worker の1つ ◦ DOM に直接アクセスできない • プログラム可能なネットワークプロキシ • App

    Cache の弱点を避けるように設計されている Service Worker
  19. ネットワークから取得する全てをキャッシュし キャッシュがあればキャッシュから返す ※HTML, CSS, JavaScript, IMG … ※オリジン、サードパーティ含めて全て Service Worker

    サンプルコード
  20. Service Worker サンプルコード

  21. Service Worker サンプルコード ネットワークへのリクエストにイベントを張る

  22. Service Worker サンプルコード 引数をレスポンスとして返す

  23. Service Worker サンプルコード キャッシュに存在するか判定

  24. Service Worker サンプルコード あれば返す

  25. Service Worker サンプルコード なければ fetch でネットワークから取得

  26. Service Worker サンプルコード キャッシュに保存

  27. Service Worker サンプルコード データを返す

  28. キャッシュがないとき 1 2 3 4 5 6

  29. キャッシュがあるとき 1 2 3

  30. • fetch にイベントを貼る • caches からキャッシュを取得 or 貯める ◦ 無いときはfetch

    で取得 • responeseWith でレスポンスを返す Service Worker がしていること
  31. 皆さん気づきましたか?

  32. • fetch にイベントを貼る • caches からキャッシュを取得 or 貯める • responeseWith

    でレスポンスを返す Service Worker がしていること caches? Local Storage…? Session Storage…? indexedDB…? こいつは何者だ・・・?
  33. Service Workerはキャッシュの仕組みを 持っているわけではない Service Worker

  34. Cache API キャッシュの仕組み

  35. • Window やWorker で使える • Cache API 単体で使える ◦ Service

    Worker と結びつけて使う必要はない • 有効期限は設定できない • Chrome 開発者ツールから中身が見れる • caches というグローバル変数が存在する Cache API
  36. None
  37. • CacheStorage Interface • match, has, open, delete, keys メソッドを持つ

    caches グローバル変数
  38. CacheStorage Interface • open (cacheName) ◦ cacheName ▪ String ◦

    Cache オブジェクトを取得する
  39. 引数の文字列を変更することで複数持つことができる Sample

  40. CacheStorage Interface • keys () ◦ Cache オブジェクトの cacheName を配列で取得する

  41. さっきの例であれば、CACHE_NAME と CACHE_NAME_2 を 取得する Sample

  42. CacheStorage Interface • has (cacheName) ◦ 引数の名前のCache オブジェクトが存在するか判定する ◦ boolean

    で受け取る
  43. Sample

  44. CacheStorage Interface • delete (cacheName) ◦ 引数の名前のCache オブジェクトを削除する ◦ boolean

    で受け取る
  45. Sample

  46. • Cache Interface • caches.open により取得できるオブジェクト • match, matchAll, add,

    addAll, put, delte, keys メソッドを 持つ Cache Object
  47. Cache Interface 追加系 • put (request, response) ◦ request ▪

    StringでURL、Requestオブジェクト ◦ response ▪ Responseオブジェクト ◦ key / value でキャッシュに追加する
  48. • 同じリクエストの場合は上書きする • レスポンスが200 以外でも追加ができる Put の補足

  49. • add (request) ◦ request ▪ StringでURL、Requestオブジェクト ◦ ネットワークから取得しキャッシュに格納する ◦

    fetch + put と同じ挙動 Cache Interface 追加系
  50. • addAll (requests) ◦ requests ▪ 配列 ◦ 配列の中身をadd する

    Cache Interface 追加系
  51. • 同じリクエストの場合は上書きする • レスポンスが200 以外の場合追加ができない Add, AddAll の補足

  52. Sample

  53. • match (request, options) ◦ request ▪ StringでURL、Requestオブジェクト ◦ options

    [optional] ◦ マッチしたResponse Object を返す ◦ マッチしないときはundefined を返す Cache Interface 取得系
  54. • ignoreSearch : boolean ◦ クエリーを無視する(v=1) • ignoreMethod : boolean

    ◦ メソッドを無視する(GET, HEAD) • ignoreVary : boolean ◦ Vary header を無視する options
  55. • matchAll (request, options) ◦ 引数はmatchと同じ ◦ Response Object の配列を返す

    Cache Interface 取得系
  56. Sample

  57. • delete (request, options) ◦ 引数はmatchと同じ ◦ キャッシュを削除する ◦ 成功したらtrue,

    失敗したらfalse を返す Cache Interface 削除系
  58. Sample

  59. • keys (request, options) ◦ request [option] ▪ リクエストを指定できる ◦

    options [option] ▪ matchと同じ ◦ keyの配列を取得する Cache Interface その他
  60. Sample キャッシュを全て削除する

  61. • 一覧で詳細で必要な静的リソースを読み込む • 古いバージョンを消して新しいキャッシュを作る • 期限付きキャッシュを作る ユースケース

  62. 一覧で詳細で必要な静的リソースを読み込む

  63. 一覧で詳細で必要な静的リソースを読み込む addAll で詳細に必要なリソースを キャッシュに追加

  64. 一覧で詳細で必要な静的リソースを読み込む fetch にイベントを貼って キャッシュにあればキャッシュから返す

  65. 一覧で詳細で必要な静的リソースを読み込む キャッシュないものは通常通り ネットワークから取得する ※想定外のリソースをキャッシュさせない

  66. 古いバージョンを消して新しいキャッシュを作る

  67. 古いバージョンを消して新しいキャッシュを作る 新しいバージョンがキャッシュにあるか判定

  68. 古いバージョンを消して新しいキャッシュを作る ignoreSearch を使うことで /app.js?v=old といったバージョン違いのキャッシュを削除できる

  69. 古いバージョンを消して新しいキャッシュを作る 古いバージョンを削除後、新しいバージョンを追加

  70. 期限付きキャッシュを作る

  71. 期限付きキャッシュを作る キャッシュにあるか判定

  72. 期限付きキャッシュを作る ない場合はキャッシュに追加し LS に現在時刻をurl をキーにして追加

  73. 期限付きキャッシュを作る ある場合は、現在時刻から1日経っているか 判定

  74. 期限付きキャッシュを作る 1日過ぎている場合は、新たにキャッシュを追 加、 LS の日付を更新する

  75. • キャッシュの上限や使用量がわかる • quota ◦ 上限 • usage ◦ 現在の使用量

    ※ただし取得できる値はバイトではなく概念値 StorageEstimate
  76. Sample 現在のキャッシュの使用割合を表示する

  77. まとめ • PWA における速度は安定して高速であること • 安定した速度はネットワークに依存をしないこと • SW ではなくCache API

    によってキャッシュされる • Cache API はSW 依存ではなく独立したAPI • add, match, delete などLS などと使い方は似ている
  78. • Cache-Control ヘッダでも似たようなことはできる • 利点はプログラミング可能なキャッシュ機能 • 例:Intersection Observer と組み合わせて画面内のリンク をキャッシュ追加,

    削除 Cache API + Service Worker の利点
  79. ご清聴ありがとうございました