キャッシュする方法は複数あります。
条件付きGET
これらのイメージをファイルシステムに格納し、Webサーバー経由で直接提供する場合は、おそらくすでに条件付きgetを使用しています。ウェブサーバーは自動的にファイルシステムメタデータを使用してETAGヘッダーを設定し、ブラウザがリクエストにIf-Modified-Since
やIf-Matches
ヘッダーを含める場合は、「304 Not Modified」で自動的に応答します。(すべてのブラウザがします。)
この場合、イメージ全体が返されないため、帯域幅を節約できます。ただし、GETリクエストは引き続き発行されるため、リクエストのオーバーヘッドとレイテンシがあります。
ウェブサーバーにCache-Control
ヘッダーにpublic,max-age=N
画像の値を設定させることで、キャッシュの鮮度を犠牲にしてリクエスト数をわずかに減らすことができます。これは、キャッシュmax-age
が更新されているかどうかを確認する前に、キャッシュがリソースを最大で数秒間保持できることを示しています。
ただし、HTTPはキャッシュエントリを無効にする方法を1つしか定義していないため、アプリケーションのセマンティクスに適合しない可能性があります。プロフィール写真を更新するURLにPOSTまたはPUTすると、Location: [url of photo]
ヘッダーで返信し、そのURLのキャッシュエントリは無効になります。
(これは、コメント付きのWebページをキャッシュし、ユーザーが新しいコメントを投稿した後、ブラウザがページを強制的に再読み込みできるようにするメカニズムです。ブラウザは、POST /comment
with 303 See Other
とに応答しLocation: /page/with/comment
ます。これは使用されていません。長期にわたるバグのため、Firefoxで動作します。)
大量のトラフィックがない限り、このキャッシュへのアプローチは問題ありません。
URLを変更する
URLはリソースの表現であるため、キャッシュを管理する別の方法は、リソースのキャッシュパラメータを変更するのではなく、「永久にキャッシュ」ディレクティブを使用して新しいリソースを作成することです。これは、「大物」が好むアプローチであり、余分な要求を生成せず、帯域幅を大幅に節約できるためです。欠点は、さらに多くの簿記が必要になることです。
これには2つの一般的な手法があります。
クエリ文字列
ファイルシステムからファイルを提供する場合、Webサーバーはクエリ文字列を無視します。:キャッシュは、しかし、ない/1.jpg?t=12345
と/1.jpg?t=67890
、サーバーはそれらが同じであると思っていても、2つの完全に異なる、無関係な資源です。
したがって、HTML内のリソースを参照するときに、ファイルシステムのタイムスタンプをクエリ文字列として追加し、長いExpires
ヘッダーを設定するのが簡単な方法です。ブラウザはない永遠にこのリソースをキャッシュしないであろう任意の長いクエリ文字列が変更されないようとして取得します。
欠点は、キャッシュを強制的に無効にしたい場合、アイテムの新しいURLをWebサーバーに指示することが困難または不可能であることです。たとえば、ブラウザに参照付きのキャッシュされたHTMLページがある/1.jpg?v=1
が、たまたまエントリがクリアされた場合/1.jpg?v=1
(ファイルまたはメモリ領域が足りなくなった可能性があります)、ブラウザはに新しいリクエストを送信し/1.jpg?v=1
ます。その間に画像がに変わった/1.jpg?v=2
場合、適切な応答は次のいずれかです。
- 古いバージョンのファイルを提供します。これは、特定の時点ですべてのリソースを互いに整合させたい場合に行います。これは、たとえば、古いhtmlファイルを含む新しいcssファイルが正しく機能しない可能性があるため、CSSファイルを使用して実行する必要があります。
- を使用して、ファイルの新しいバージョンにリダイレクトします
301 Moved Permanently
。すべてのリソースをできるだけ新しくしたい場合は、これを行います。
これらの両方をWebサーバーだけで行うのは困難です。つまり、画像要求に対してもWebアプリケーションを呼び出す必要があり、より複雑でリソースを大量に消費する可能性があります。ウェブサーバーはファイルを提供する速度が非常に速いため、ウェブアプリケーションのオーバーヘッドによって、帯域幅とレイテンシが増加する可能性があります。
ファイル名
クエリ文字列を追加する代わりに、ファイル名を変更します。つまり、ファイルシステムにファイルの複数のバージョンを保持するのは簡単ですが、リソースとその名前を追跡するには、ファイルメタデータを保存し、他のデータベースブックキーピングを行う必要があるでしょう。