なにがキャッシュされるのか ~Webサイトの性質ごとの違い
はじめに
Webサイト・Webアプリケーションの制作において、キャッシュの管理はUXに大きな影響を与える重要な要素です。
キャッシュを適切に運用することで
- 通信量・回数の軽減
が行われ、ユーザーへのレスポンス速度の向上が望めるだけでなく
- サーバーへのリクエストが軽減
することでサーバー負荷の軽減をすることができ、コストやパフォーマンスのさらなるメリットを期待することができます。
一方で、適切にキャッシュを扱えなかった場合には
- ユーザーに表示する情報が更新されない
- 情報の整合性を保てない
- 見せるべきでない情報が漏洩する
などのパフォーマンスだけでなくセキュリティ上のリスクにさえなりえます。
本記事では、Webサイトの性質ごとになにがキャッシュされるのか、何をキャッシュするべきかについて整理します。
ローカルキャッシュと共有キャッシュ
キャッシュは大きく2種類にわけることができます
ローカルキャッシュ
- ブラウザキャッシュともいい、ユーザーのブラウザからローカルファイルとして保存される
- キャッシュを利用するときに通信が発生しない
- 他のユーザーは閲覧することができない
共有キャッシュ
- CDNやプロキシサーバーなどがキャッシュサーバーとなり、リソースを保存しているオリジンサーバーへ向かうネットワーク経路上に保存される
- キャッシュを利用する際にキャッシュサーバーまでの通信が発生する
- 他のユーザーがキャッシュを利用できる(こともある)
本記事では共有キャッシュを例に挙げて説明しますが、ローカルキャッシュでも同じ考え方を使える部分は多いです。
静的なWebサイト
まず、静的サイトについて考えましょう。
静的サイトとは、ここではhtml・css・画像・jsなどによって構成され、オリジンサーバーに保存されている情報のみでユーザーに表示ができるサイトを指します。
オリジンサーバーの前段にCDNを配置したとき、次のような通信が発生します。
CDNにキャッシュがあるとき、オリジンサーバーへの問い合わせが発生しなくなっていることがわかります。
ここでキャッシュされているのは、キャッシュがない時に取得していたものと同様のリソースです。これらに対して有効期限などの設定を行うことでキャッシュをコントロールします。
WebAPIを通してデータを取得するサイト
次に、クライアントからjavascriptでWebAPIを呼び出し、取得したjsonデータを元にコンテンツをレンダリングするケースについて考えます。SPAでのクライアントサイドレンダリングもこれにあたります。
まず、先ほどと同様にWebサーバの前段にCDNを置いてみましょう。
静的リソースはキャッシュの恩恵を受けることができますが、キャッシュがある時もAPIサーバとの通信は削減されていないことがわかります。
これだけで十分か、APIリクエストをキャッシュ必要するかは要件に応じた検討が必要となるでしょう。
APIをキャッシュする
APIサーバーへのリクエストを減らすために前段にCDNを配置し、うまくキャッシュできた場合は次のようになります。
これであればAPIサーバーへの問い合わせは発生しません。
一方で、APIのはいくつか考慮事項が増えます。
たとえば、APIのレスポンス結果はキャッシュの有効性を検証するのが難しいことがあります。静的なファイルであればファイルの更新日やハッシュから更新が発生しているかを判断できますが、APIではDBへアクセスするなど実際の処理を行わなければキャッシュの検証ができないことがあります。この対策として、実際に更新されているかに関わらず、更新されるであろう期間に応じてTTLを設定するなどの手法があります。厳密な整合性を求める場合には注意が必要です。
また、リクエストする人によりレスポンスの結果がことなるケースも考えられます。たとえば認証情報に応じて自身のプロフィールを取得する/me
というAPIがあるとき、パスだけでレスポンスをキャッシュしてしまうと、違うユーザーのプロフィールを取得してしまうことがありえます。これを避けるためにはparameterや認証情報をキャッシュのキーに使えるか、そもそもキャッシュしてよいデータなのか、などの検討が必要です。
動的に再生するサイトのキャッシュ
次にサーバー側で動的にhtmlを生成するサイト(MVCフレームワークやRPAなどのSSR)を考えてみます。
レンダリングされた静的コンテンツがキャッシュされているのがわかります。レンダリングされたhtmlのキャッシュの有効期限をどうするか、という課題は前節と同様に検討が必要になります。1つのhtmlを生成するのに複数APIを用いている場合は、一番短い更新タイミングに合わせることになるなどが追加の考慮点です。
まとめ
- キャッシュにはローカルキャッシュと共有キャッシュがある
- サイトの構成によりなにがキャッシュされるかを考える
- 動的なコンテンツをキャッシュするには考慮事項が増える
最後に
整理したコンテンツに対して「どうやって」キャッシュの制御を行うか、これが一番書きたかったところなのですが、前段を一度整理する必要があったので独立した記事としました。
NCDC株式会社( ncdc.co.jp/ )のエンジニアチームです。 募集中のエンジニアのポジションや、採用している技術スタックの紹介などはこちら( github.com/ncdcdev/recruitment )をご覧ください! ※エンジニア以外も記事を投稿することがあります
Discussion