この記事は、現在開催中のイベント「フロントエンド強化月間 - 開発する上で知っておくべき知見を共有しよう」の記事です。
はじめに
QiitaではService Workerを使い、リソースをクライアントにキャッシュさせることにより、パフォーマンスの向上、リクエスト数の軽減をしている。
Service Workerでキャッシュを扱うにあたって、いくつかのキャッシュ戦略があるため、それを紹介する。
Service Workerについて
Workbox
Qiitaでは、Service Workerファイルの生成にWorkboxを使っている。
Workboxは、gatsby-plugin-offline、next-offlineとかにも使われているライブラリで、Googleが開発している。
Service Workerを簡単に書くことができるのがウリ。
キャッシュ戦略
プリキャッシュ(事前キャッシュ)
Service Workerのinstall時に、キャッシュを行う。
一度キャッシュされると、次回以降そのリソースをロードする場合はキャッシュからロードされる。
Service Workerのinstall時にキャッシュがされるため、Service Workerが更新されないかぎり、キャッシュが変わることはない。そのため、デプロイ時などにService Workerを更新させる必要がある。
ランタイムキャッシュ
プリキャッシュとは異なり、実際にリソースが必要になったタイミングでキャッシュを行うかの処理が行われる。
このタイミングでの処理には以下の種類がある。
- Stale While Revalidate
- Cache First
- Network First
- Network Only(略)
- Cache Only(略)
Stale While Revalidate
俗に言うSWR
というやつ。
はじめにキャッシュを探し、キャッシュがある場合はキャッシュから返す。そして、裏側でネットワークから新しいレスポンスを受け取り、キャッシュに格納をしておく。
キャッシュから読み込むため、はやい。そして、裏側でキャッシュの更新を行っているため、キャッシュが古すぎるという問題が起きない。
ただし、リソース削除後に、ユーザー側に消す前のリソースがキャッシュされている場合、消されたリソースが見れてしまうなどの問題点もある。
Cache First
キャッシュがある場合は、キャッシュから返し、ネットワークにはアクセスをしない。もし、キャッシュがない場合は、ネットワークからリソースを受け取る。
一度キャッシュされると、次回以降はネットワークにはリクエストが飛ばないため、リクエスト数やデータ転送量を削減したいときには有効。
ただし、キャッシュを更新/削除しない限り、古いキャッシュを見続けるため、キャッシュの有効期限を設定したり、リソース名にハッシュをつけたりなどの工夫が必要である。
Network First
ネットワークに問題がない場合に、ネットワークからリソースを受け取る。受け取ったリソースはキャッシュに格納しておき毎回更新される。そして、ネットワークエラーなどが起きた際には、キャッシュからリソースを返す。
基本、ネットワークからリソースを受け取るため、リソースが古いなどは起こらない。ネットワークエラーが起きた際にキャッシュから返すことができるため、アプリケーションのオフライン化に活用できる。
おわりに
ユーザー側にキャッシュが残ってしまい、事故を起こす可能性があるため、キャッシュ戦略は慎重にやりましょう!