Webサイトの表示速度を向上させる技術の一つとして「HTTPキャッシュ」がありますが、その中で重要な役割を果たすのがステータスコード304です。
「304 Not Modified」はブラウザのキャッシュが有効であることを示し、サーバーから改めてデータを取得せずに済むことを意味します。
本記事では、ステータスコード304の仕組みとHTTPキャッシュの基本原理、If-Modified-Sinceヘッダーとの関係、パフォーマンス向上への貢献まで詳しく解説します。
Webパフォーマンスに興味があるエンジニアや、サーバー負荷削減を目指す開発者にとって参考になる内容でしょう。
ステータスコード304(Not Modified)とは?基本的な仕組み
それではまず、ステータスコード304の基本的な意味とHTTPキャッシュにおける役割について解説していきます。
「304 Not Modified」はクライアントが条件付きGETリクエストを送信した際、リクエストされたリソースが前回取得時から変更されていない場合にサーバーが返すコードです。
304を受け取ったブラウザはサーバーから新たにデータを受け取る必要がなく、ローカルキャッシュからリソースを取得して表示するため、通信量の削減とページ表示の高速化が実現できます。
304レスポンスの特徴
レスポンスボディなし:データ転送が不要なため、レスポンスボディは含まれない
キャッシュ活用:ブラウザは保持しているキャッシュをそのまま使用する
パフォーマンス向上:不要なデータ転送を省略してページ表示を高速化
サーバー負荷軽減:レスポンスボディ送信がないため、帯域とサーバー負荷を削減
条件付きGETリクエストとは
条件付きGETリクエストはリクエストヘッダーに条件を含むGETリクエストであり、「前回取得時から変更があった場合のみ新しいデータを返してください」という意図をサーバーへ伝えます。
代表的なものが「If-Modified-Since」と「If-None-Match」の2種類のヘッダーで、これらが含まれるリクエストに対してサーバーは変更がない場合に304を返します。
条件付きリクエストと304の組み合わせによってHTTPキャッシュの効率的な活用が実現されるでしょう。
If-Modified-SinceヘッダーとLast-Modifiedの関係
ブラウザが最初にリソースを取得した際、サーバーはレスポンスヘッダーに「Last-Modified: [リソースの最終更新日時]」を含めて返します。
次回同じリソースをリクエストする際、ブラウザは「If-Modified-Since: [前回取得時のLast-Modified値]」ヘッダーを付けてリクエストを送信します。
サーバーはIf-Modified-Sinceで指定された日時以降にリソースが更新されていなければ304を返し、更新されていれば新しいデータとともに200を返すでしょう。
ETagとIf-None-Matchを使ったキャッシュ制御
続いては、より精度の高いキャッシュ制御を実現するETagとIf-None-Matchの仕組みを確認していきます。
ETagとは何か
ETag(Entity Tag)はリソースの特定バージョンを識別するためのハッシュ値などの一意な文字列であり、サーバーがレスポンスヘッダーに「ETag: “abc123″」の形式で返します。
Last-Modifiedが時刻ベースの検証であるのに対し、ETagはリソースの内容に基づく検証を行うため、1秒以内の更新やタイムゾーン問題など時刻ベース検証の弱点を補うことができます。
ETagを用いた条件付きリクエストでは「If-None-Match: “abc123″」ヘッダーを付けてリクエストを送り、サーバーが同じETag値であれば304を返す仕組みです。
| 条件付きヘッダー | 対応するサーバーレスポンスヘッダー | 検証方式 |
|---|---|---|
| If-Modified-Since | Last-Modified | 最終更新日時による比較 |
| If-None-Match | ETag | ETagハッシュ値による比較 |
304の実際のHTTP通信の流れ
初回リクエスト時:ブラウザがGETリクエスト送信 → サーバーが200とリソース・ETag・Last-Modifiedを返す → ブラウザがキャッシュに保存
2回目リクエスト時:ブラウザがIf-None-Match(ETag値)またはIf-Modified-Since(日時)を付けてGETリクエスト送信 → サーバーが変更なしと判断して304を返す(ボディなし)→ ブラウザがキャッシュからリソースを表示
この流れによってネットワーク転送量を最小化しながら常に最新のリソースを確認できる効率的なキャッシュ機構が実現されるでしょう。
Cache-ControlとExpiresによる強キャッシュ
304を使った条件付きリクエストは「弱キャッシュ(検証キャッシュ)」と呼ばれますが、Cache-ControlのMax-ageやExpiresヘッダーによる「強キャッシュ」では有効期間中はサーバーへのリクエスト自体が省略されます。
「Cache-Control: max-age=86400」(1日)と設定されたリソースは有効期間内は304の確認すら不要で完全にキャッシュから取得されます。
静的ファイル(JS・CSS・画像)には強キャッシュ、動的コンテンツには弱キャッシュを組み合わせることが効果的なキャッシュ戦略でしょう。
304を活用したWebパフォーマンス向上の実践
続いては、304レスポンスを効果的に活用してWebサイトのパフォーマンスを向上させる実践的な方法を確認していきます。
Webサーバーでの304設定確認
ApacheとnginxはデフォルトでETagとLast-Modifiedを付与するため、特別な設定なしに304キャッシュが機能します。
ただし、ロードバランサー環境でサーバーごとにETag値が異なる場合(非一貫性ETag問題)は、ETagを無効化してLast-Modifiedのみで制御するか、分散環境での一貫したETag生成方式を採用することが推奨されます。
「apache2 -v | grep version」などのコマンドでWebサーバーのバージョンとETag設定を確認するとよいでしょう。
ブラウザキャッシュの確認方法
Chrome開発者ツールのNetworkタブで「Disable cache」のチェックを外した状態でリロードすると、実際に304レスポンスが返されているリソースを確認できます。
サイズカラムに「(disk cache)」や「(memory cache)」と表示されているリソースはキャッシュから取得されており、「304」と表示されるものは条件付きリクエストによって確認されたことを示します。
これらの情報を元にキャッシュが適切に機能しているかを確認することができるでしょう。
APIでの304活用と注意点
REST APIでも304を活用することで、クライアントとサーバー間の不要なデータ転送を削減できます。
レスポンスにETagを含め、クライアントがIf-None-Matchを付けてポーリングすることで、データ変更がない場合の帯域消費を最小化できます。
APIの304実装では「変更があった場合に必ず新しいETagを返す」ことを徹底することがキャッシュの整合性維持に不可欠でしょう。
まとめ
ステータスコード304(Not Modified)はHTTPキャッシュの仕組みの中核を担うコードであり、条件付きGETリクエストとの組み合わせによって不要なデータ転送を省略し、Webパフォーマンスを大幅に向上させます。
If-Modified-SinceとLast-Modified・ETagとIf-None-Matchの2種類のキャッシュ検証メカニズムを理解し、適切に活用することでサーバー負荷の軽減とユーザー体験の向上が実現できます。
強キャッシュと弱キャッシュを組み合わせたキャッシュ戦略を設計することで、高速で効率的なWebサービスの構築につながるでしょう。