コンテンツへスキップ

Workboxのプラグインについて

PWAにおいて肝となるのがキャッシュです。あるURLにアクセスした時にコンテンツを返却するのがキャッシュですが、HTML5におけるCACHE APIはすべてプログラムから操作しなければならず、実装が大変です。

そこで使ってみたいのがWorkboxになります。Google製のPWAにおけるキャッシュコントロールを便利にしてくれるライブラリになります。今回はWorkboxに対応しているプラグインと、その機能を紹介します。

workbox.backgroundSync.Plugin

ネットワークがオフラインだった場合、オンラインになったタイミングで同期してくれます。queueArgsとしてキューに送信する引数を指定します。

workbox.broadcastUpdate.Plugin

キャッシュを更新した時に、それをメッセージングしてくれます。メインスレッドのJavaScriptで受け取ったならば、表示を更新したりユーザに再読込を促したりできるでしょう。チャンネル名を指定します。

オプションは以下の通りです。

  • headersToCheck
    チェックするヘッダーを指定。
  • source
    データ元のソースを指定。

workbox.cacheableResponse.Plugin

キャッシュする際のヘッダーレスポンスを指定。

オプションは以下の通りです。

  • statuses
    キャッシュするHTTPレスポンスコードを配列で指定。
  • headers
    キャッシュするHTTPレスポンスヘッダーをオブジェクトで指定。

workbox.expiration.Plugin

キャッシュに有効期限を付けられるプラグイン。

オプションは以下の通りです。

  • maxEntries
    最大の登録数。
  • maxAgeSeconds
    有効期限。秒で指定。
  • purgeOnQuotaError
    容量制限に引っかかった場合はエラーにするかどうか。

workbox.rangeRequests.Plugin

HTTPのRangeへのアクセス対応用です。分割ファイルをリクエスト、キャッシュするのに使います。

自作プラグインの作り方

プラグインは以下の5つのメソッドを持ったオブジェクトになります。

  • cacheWillUpdate
  • cacheDidUpdate
  • cachedResponseWillBeUsed
  • requestWillFetch
  • fetchDidFail

Workboxを使えばキャッシュのコントロールが柔軟になります。プラグインを使ったり、自作することでより簡単に実装できるようになるでしょう。ぜひ使い方を覚えましょう。

Workbox | Google Developers

Workboxでキャッシュの有効期限を付ける

PWAのCACHE APIにおいて問題になりがちなのが、キャッシュが更新されないということです。基本的にプログラム側から削除や更新しない限り、キャッシュは恒久的に残り続けます。

Googleが開発するWorkboxを使えば、キャッシュに有効期限を設けられます。そうすれば一定時間経過すれば自動的にキャッシュがなくなってコンテンツがリフレッシュされます。

有効期限の付け方

有効期限を設ける時には、キャッシュ作成時に workbox.expiration.Plugin を指定します。

これを見て分かる通り、キャッシュ名を指定して作成するので、有効期限はキャッシュ名単位になります。一般的にはキャッシュ名を一つで運用してしまいがちですが、リソースの種類によって有効期限を変えるのは面白そうです。


キャッシュコントロールの難しさがPWAの導入を遅らせているとも言えます。Workboxを使って、キャッシュを適切にコントロールしてください。

Workbox  |  Google Developers

Workboxを使ってPWAのキャッシュを作成する

Googleが提供するWorkboxはService Workerを使う上で必須とも言える機能を提供してくれます。特にキャッシュ周りの面倒な操作を手軽に行ってくれるのが利点です。

今回はそんなWorkboxでキャッシュを作成する方法を紹介します。

インストール

Workboxのインストールはローカルにファイルを設置することもできますが、importScriptsでリモートファイルを指定するのが最も簡単です。

これで workbox というグローバル変数が定義されます。

パターンで登録する

一般的にキャッシュを作成する場合、URL単位で指定します。しかしWorkboxの場合は正規表現パターンで指定できます。

このように定義することで、 *.js のリクエストに対してはキャッシュファーストで返してくれるようになります。他にも workbox.strategies.networkFirst()workbox.strategies.staleWhileRevalidate() も用意されています。


キャッシュを正規表現で指定することで、多数のファイルをまとめてキャッシュ化できます。特定ファイルはキャッシュしないというポリシーであっても、正規表現で指定すれば問題ありません。WorkboxはService Worker利用時には欠かせないツールと言えます。ぜひ使いこなしてください!

Workbox  |  Google Developers

PWAでキャッシュされているファイルを確認する

PWAではService WorkerのCACHE APIを使ってファイルをキャッシュできます。それを使えばオフライン時にもリソース(画像やJavaScriptファイルなど)を返せるので、ネットワークに繋がっていなくともWebアプリケーションが使い続けられます。

PWAを開発している際に、ファイルがキャッシュされているか、さらにキャッシュされてしまったファイルを簡単に削除する方法を紹介します。

キャッシュファイルの確認

Google Chromeを使っている場合、開発者ツールのApplicationタブにあるCache Storageからキャッシュされているコンテンツであったり、キャッシュされている内容の確認もできます。

これを使えば正しくキャッシュされているかどうか、すぐに確認できます。

キャッシュの削除

キャッシュの一覧を右クリックすると、リフレッシュと削除が表示されます。プログラムでキャッシュを更新することもできますが、開発中であれば開発者ツールから行うのが簡単です。


CACHE APIは非常に強力で、キャッシュの更新や削除をしないと恒久的に残り続けてしまいます。開発中、最初から更新や削除の仕組みがある訳ではないと思いますので、開発者ツールを使う方法を覚えておくと便利です。

GoではじめるWebAssebmly その5「ウィンドウオブジェクト、localStorageを使う」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はさらに面白い、ウィンドウオブジェクトやlocalStorageをWebAssemblyから使ってみます。

オンライン、オフラインを検知する

Webアプリケーションのネットワーク状態を受け取るには window オブジェクトの online または offline イベントを使います。これももちろんGoのWebAssemblyの中に記述できます。

そしてオンライン、オフラインの値は navigator.onLine で取れますので、この値も使います。

 

これでWebAssembly側でもオンライン、オフラインの判定ができるようになります。

localStorageを使う

さらにWebブラウザとWebAssemblyでデータの送受信をする際に使ってみたいのがlocalStorageを経由したデータ授受です。

 

 

このようなコードで localStorage に触って、データをセットしたり、値の取得を行えます。localStorageの場合、setItemやgetItemではなくSet/Getで値の授受ができるのが特徴です。 localStorage.Call("setItem", "Hello", "World") ではうまくいきませんが、 localStorage.Get("getItem", "JavaScript") は利用できます。


syscall/js は非常によくできており、同時に利用する wasm_exec.js と組み合わせることでWebAssemblyからDOMやJavaScriptのAPIを透過的に扱えます。ちょっとした使い方さえ覚えてしまえばJavaScriptと変わらず使えるようになりそうです。

オンライン、オフライン判定などWebAssemnly単体では難しいことも容易に実現できます。ぜひGoでWebAssemblyを使ってみてください。

GoではじめるWebAssebmly その4「POST系ネットワーク処理」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はネットワーク処理(POST処理)の書き方を解説します。

使いどころ

POSTやPUT、DELETEはREST APIを扱うのに使われるでしょう。今回はPOSTリクエストでJSONを送信する方法を解説します。

ボタンを押したタイミングで処理

例えば今回はボタンを押したタイミングで入力されている内容をJSON化して送信します。そこでボタンのクリックイベントを設定します。

goroutineに注意

ネットワーク処理は非同期なのでデータを安全に送受信するためにgoroutineが使われています。そして単純にPOST処理を書くと、WebAssebmly全体で設定しているgoroutineが終了してデッドロックが発生してしまいました。

そこで処理全体を無名関数化して、それをgoで実行(goroutine化)します。

via runtime: wasm: all goroutines asleep and no JavaScript callback pending – deadlock · Issue #26382 · golang/go

この問題は 1.12 で直る予定です。

CORSに注意

Goでhttp.Postを使っていますが、実際にはWebブラウザのメインスレッド側でリクエスト処理が行われます。CORSは通常のJavaScriptと変わらず行われます。また、ネットワーク接続内容などは開発者ツールで見られますので、隠蔽できる訳ではありません。


Goを使ったWebAssemblyは他の言語では見られないDOM操作とネットワークアクセスが可能です。これは大きなメリットと言えるでしょう。ぜひこの特徴を活用し、高速で安全なWebアプリケーションを開発してください。

GoではじめるWebAssebmly その3「GET系ネットワーク処理」

WebAssebmlyはWebブラウザ上でバイナリファイル(テキスト形式もあり)を実行できる環境です。JavaScriptと異なりコードの漏洩がなく、実行速度も高速というのがメリットです。

WebAssebmlyは元々Rustで開発することが多かったですが、最近では様々なプログラミング言語が対応しています。その一つがGoです。Go 1.11からWebAssembly向けにもコンパイルできるようになっています。

一般的なWebAssemblyはDOMやネットワーク操作が行えません。それに対してGo 1.11ではJavaScript APIを使えるようにした syscall/js パッケージを用いることで、DOMやネットワーク操作を可能にしています。

そこで今回はネットワーク処理(GET処理)の書き方を解説します。

使いどころ

GET処理の使いどころはもちろん、Web APIからのデータ取得になるはずです。今回は文字列が配列で返ってくるケースを紹介します。

JSONを利用するためには構造体を定義する必要あり

Goの若干面倒な部分として、JSONを利用するためには構造体を定義する必要があるという点があげられます。例えば以下のような形です。

ネットワークは net/http で行う

Goでネットワーク処理を記述する場合には net/http ライブラリを使います。

処理について

例えばあるドメイン domain からJSON文字列を取得するデモコードです。

後はこの関数を実行します。


これでJSONの取得とパースが完了します。なお、見ての通り、このコードはネットワーク部分を同期的に処理しています。関数の頭に go をつけることで非同期処理になりますが、描画部分を考えると同期(または描画を含めて非同期)処理にしなければなりません。

また、このネットワーク接続はWebAssemblyの中で行われているのではなく、メインスレッド側で行われます。そのため開発者ツールなどでリクエスト内容は確認できます。ネットワーク接続を秘匿にするのは困難なので、注意してください。