Slide 1

Slide 1 text

PWAとCache API Wataru Taguchi

Slide 2

Slide 2 text

● 自己紹介 ● PWA ● Service Worker ● Cache API ● まとめ アジェンダ

Slide 3

Slide 3 text

# Wataru Taguchi - GameWith Engineer - PWA, Web Components, AMP - パフォーマンスチューニングが好き - @tiwu_official - FF14, ストファイ5, Beer, Kyoto Animation 自己紹介

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

Progressive Web App PWA

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

● PWA はブラウザでも見れるが、インストールもできる ● ブラウザのブックマークとは異なり、ネイティブアプリと同様にホーム画面に追加さ れる ● スプラッシュスクリーン、アイコンなどでカスタマイズ可能 ● アドレスバーなどのブラウザUIのない独立したアプリとして起動する ● PWA をインストールするユーザーはネットワーク接続がどのような状態でも起動す ることを期待する ● DEMO https://twitter.com/i/status/1100018179479224321 インストール可能

Slide 9

Slide 9 text

● レスポンシブデザインによりモバイル&デスクトップで動作する ● コードはプラットフォームによらずHTML、CSS、JavaScript モバイル&デスクトップ

Slide 10

Slide 10 text

PWAにおける速度とは

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

● PWA はブラウザでも見れるが、インストールもできる ● ブラウザのブックマークとは異なり、ネイティブアプリと同様にホーム画面に追加さ れる ● スプラッシュスクリーン、アイコンなどでカスタマイズ可能 ● アドレスバーなどのブラウザUIのない独立したアプリとして起動する ● PWA をインストールするユーザーはネットワーク接続がどのような状態でも起動す ることを期待する ● DEMO https://twitter.com/i/status/1100018179479224321 インストール可能

Slide 13

Slide 13 text

どのようなネットワークの状態でも 安定して高速であること PWAにおける速度とは

Slide 14

Slide 14 text

● Wi-Fi ● 4G,3G ● 速度制限 ● オフライン ● etc... ネットワークの状態

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

● Worker の1つ ○ DOM に直接アクセスできない ● プログラム可能なネットワークプロキシ ● App Cache の弱点を避けるように設計されている Service Worker

Slide 19

Slide 19 text

ネットワークから取得する全てをキャッシュし キャッシュがあればキャッシュから返す ※HTML, CSS, JavaScript, IMG … ※オリジン、サードパーティ含めて全て Service Worker サンプルコード

Slide 20

Slide 20 text

Service Worker サンプルコード

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

● fetch にイベントを貼る ● caches からキャッシュを取得 or 貯める ○ 無いときはfetch で取得 ● responeseWith でレスポンスを返す Service Worker がしていること

Slide 31

Slide 31 text

皆さん気づきましたか?

Slide 32

Slide 32 text

● fetch にイベントを貼る ● caches からキャッシュを取得 or 貯める ● responeseWith でレスポンスを返す Service Worker がしていること caches? Local Storage…? Session Storage…? indexedDB…? こいつは何者だ・・・?

Slide 33

Slide 33 text

Service Workerはキャッシュの仕組みを 持っているわけではない Service Worker

Slide 34

Slide 34 text

Cache API キャッシュの仕組み

Slide 35

Slide 35 text

● Window やWorker で使える ● Cache API 単体で使える ○ Service Worker と結びつけて使う必要はない ● 有効期限は設定できない ● Chrome 開発者ツールから中身が見れる ● caches というグローバル変数が存在する Cache API

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

● CacheStorage Interface ● match, has, open, delete, keys メソッドを持つ caches グローバル変数

Slide 38

Slide 38 text

CacheStorage Interface ● open (cacheName) ○ cacheName ■ String ○ Cache オブジェクトを取得する

Slide 39

Slide 39 text

引数の文字列を変更することで複数持つことができる Sample

Slide 40

Slide 40 text

CacheStorage Interface ● keys () ○ Cache オブジェクトの cacheName を配列で取得する

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

CacheStorage Interface ● has (cacheName) ○ 引数の名前のCache オブジェクトが存在するか判定する ○ boolean で受け取る

Slide 43

Slide 43 text

Sample

Slide 44

Slide 44 text

CacheStorage Interface ● delete (cacheName) ○ 引数の名前のCache オブジェクトを削除する ○ boolean で受け取る

Slide 45

Slide 45 text

Sample

Slide 46

Slide 46 text

● Cache Interface ● caches.open により取得できるオブジェクト ● match, matchAll, add, addAll, put, delte, keys メソッドを 持つ Cache Object

Slide 47

Slide 47 text

Cache Interface 追加系 ● put (request, response) ○ request ■ StringでURL、Requestオブジェクト ○ response ■ Responseオブジェクト ○ key / value でキャッシュに追加する

Slide 48

Slide 48 text

● 同じリクエストの場合は上書きする ● レスポンスが200 以外でも追加ができる Put の補足

Slide 49

Slide 49 text

● add (request) ○ request ■ StringでURL、Requestオブジェクト ○ ネットワークから取得しキャッシュに格納する ○ fetch + put と同じ挙動 Cache Interface 追加系

Slide 50

Slide 50 text

● addAll (requests) ○ requests ■ 配列 ○ 配列の中身をadd する Cache Interface 追加系

Slide 51

Slide 51 text

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

Slide 52

Slide 52 text

Sample

Slide 53

Slide 53 text

● match (request, options) ○ request ■ StringでURL、Requestオブジェクト ○ options [optional] ○ マッチしたResponse Object を返す ○ マッチしないときはundefined を返す Cache Interface 取得系

Slide 54

Slide 54 text

● ignoreSearch : boolean ○ クエリーを無視する(v=1) ● ignoreMethod : boolean ○ メソッドを無視する(GET, HEAD) ● ignoreVary : boolean ○ Vary header を無視する options

Slide 55

Slide 55 text

● matchAll (request, options) ○ 引数はmatchと同じ ○ Response Object の配列を返す Cache Interface 取得系

Slide 56

Slide 56 text

Sample

Slide 57

Slide 57 text

● delete (request, options) ○ 引数はmatchと同じ ○ キャッシュを削除する ○ 成功したらtrue, 失敗したらfalse を返す Cache Interface 削除系

Slide 58

Slide 58 text

Sample

Slide 59

Slide 59 text

● keys (request, options) ○ request [option] ■ リクエストを指定できる ○ options [option] ■ matchと同じ ○ keyの配列を取得する Cache Interface その他

Slide 60

Slide 60 text

Sample キャッシュを全て削除する

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

● キャッシュの上限や使用量がわかる ● quota ○ 上限 ● usage ○ 現在の使用量 ※ただし取得できる値はバイトではなく概念値 StorageEstimate

Slide 76

Slide 76 text

Sample 現在のキャッシュの使用割合を表示する

Slide 77

Slide 77 text

まとめ ● PWA における速度は安定して高速であること ● 安定した速度はネットワークに依存をしないこと ● SW ではなくCache API によってキャッシュされる ● Cache API はSW 依存ではなく独立したAPI ● add, match, delete などLS などと使い方は似ている

Slide 78

Slide 78 text

● Cache-Control ヘッダでも似たようなことはできる ● 利点はプログラミング可能なキャッシュ機能 ● 例:Intersection Observer と組み合わせて画面内のリンク をキャッシュ追加, 削除 Cache API + Service Worker の利点

Slide 79

Slide 79 text

ご清聴ありがとうございました