HTTPキャッシュ101:知っておくべきこと
Takashi Yamamoto
Infrastructure Engineer · Leapcell

HTTPキャッシュとは
HTTPキャッシュは、サーバーの負荷を軽減し、クライアントの応答時間を短縮し、ネットワーク帯域幅を節約することで、ウェブのパフォーマンスを向上させる技術です。HTTPキャッシュには、強制キャッシュとネゴシエートキャッシュの2種類があります。
強制キャッシュ
強制キャッシュでは、クライアントはサーバーにリクエストを送信せずに、指定された期間内にローカルにキャッシュされたリソースを直接使用できます。強制キャッシュは、サーバーによって指定されたレスポンスヘッダーによって制御され、主にCache-ControlとExpiresの2つのフィールドを介して制御されます。
Cache-Control
Cache-Controlは、最大有効期間(max-age
)、キャッシュを共有できるかどうか(public
またはprivate
)、および変更を許可するかどうか(no-cache
またはno-store
)を指定する汎用ヘッダーです。
例:
Cache-Control: max-age=3600
上記は、リソースが3600秒間有効であり、キャッシュできることを示しています。
Expires
Expiresは、キャッシュの絶対的な有効期限を指定する非推奨のフィールドです。
例:
Expires: Wed, 23 Aug 2024 03:36:26 GMT
これは、リソースが2024年8月23日の午前3時36分26秒に期限切れになることを意味します。 Cache-ControlとExpiresの両方が存在する場合、Cache-Controlが優先されます。
ネゴシエートキャッシュ
ネゴシエートキャッシュでは、クライアントはリクエストごとにリソースが更新されたかどうかをサーバーに確認する必要があります。更新されていない場合、サーバーは304
ステータスコードと空のレスポンスボディで応答し、クライアントはローカルキャッシュを引き続き使用できます。更新されている場合、サーバーは200
ステータスコードと新しいリソースを返し、ローカルキャッシュを置き換えます。ネゴシエートキャッシュには、サーバーとクライアントの両方からのヘッダーが含まれ、主にLast-Modified/If-Modified-SinceとETag/If-None-Matchが含まれます。
Last-Modified/If-Modified-Since
Last-Modifiedは、リソースの最終更新時刻を示すサーバー側のフィールドです。例:
Last-Modified: Tue, 22 Aug 2024 02:36:26 GMT
これは、リソースが2024年8月22日の午前2時36分26秒に最後に変更されたことを意味します。
If-Modified-Sinceは、リソースの最終取得時刻を示すクライアント側のフィールドです。例:
If-Modified-Since: Tue, 22 Aug 2024 02:36:26 GMT
これは、クライアントが2024年8月22日の午前2時36分26秒にリソースを取得したことを意味します。 2つのタイムスタンプが等しいか、Last-Modifiedがより早い場合、リソースは更新されていません。Last-Modifiedがより遅い場合、リソースは更新されています。
ETag/If-None-Match
ETagは、リソースの一意の識別子を表すサーバー側のフィールドです。例:
ETag: '5d3a9f6d-1f86'
これは、リソースの識別子が"5d3a9f6d-1f86"
であることを示しています。
If-None-Matchは、リソースの予期される識別子を示すクライアント側のフィールドです。例:
If-None-Match: '5d3a9f6d-1f86'
これは、クライアントがリソース識別子が"5d3a9f6d-1f86"
であることを期待していることを示しています。
2つの値が一致する場合、リソースは更新されていません。異なる場合、リソースは更新されています。
HTTPキャッシュのベストプラクティス
ネゴシエートキャッシュと強制キャッシュを組み合わせることで、不要なネットワークリクエストを効果的に削減しながら、ユーザーが常に最新のコンテンツを利用できるようにすることができます。
一般的なアプローチ:
強制キャッシュ:静的リソース(CSS、JS、画像など)の場合、キャッシュ期間を長く設定します。これにより、ブラウザはサーバーに接続せずに、ローカルストレージから直接リソースを取得できます。
ネゴシエートキャッシュ:変更される可能性のあるリソースの場合、ネゴシエートキャッシュを使用します。ブラウザはリソースが変更されたかどうかを確認するためにリクエストを送信します。変更されていない場合、サーバーは304 Not Modified
レスポンスで応答し、ブラウザはローカルキャッシュを使用できます。リソースが変更された場合、サーバーは200 OK
と更新されたリソースで応答します。
実装例:
Express.jsをバックエンドフレームワークとして使用していると仮定します。
const express = require('express'); const app = express(); // 強制キャッシュ:静的リソースのキャッシュを設定 app.use( '/static', express.static('public', { maxAge: '1y', // キャッシュ期間は1年 }) ); // ネゴシエートキャッシュ:ETagとLast-Modifiedを使用 app.get('/resource', (req, res) => { const content = '...'; // リソースコンテンツを取得 const etag = generateETag(content); // ETagを生成 // If-None-Matchヘッダーを確認 if (req.headers['if-none-match'] === etag) { res.status(304).end(); // リソースは変更されていません。304を返す } else { res.setHeader('ETag', etag); res.send(content); // リソースが変更されました。新しいコンテンツを返す } }); function generateETag(content) { return require('crypto').createHash('md5').update(content).digest('hex'); } app.listen(3000, () => { console.log('Server is running on port 3000'); });
主な考慮事項
-
バージョン管理:強制キャッシュの効果を最大化するには、リソースURLにバージョン情報を含めます。例:
/static/js/main.2024082301.js
。リソースが更新されたら、バージョン番号を変更して、ユーザーが常に最新バージョンを入手できるようにします。 -
ネゴシエートキャッシュのコスト:ネゴシエートキャッシュは不要なデータ転送を削減しますが、それでもネットワークラウンドトリップが必要です。変更がほとんどないリソースの場合、強制キャッシュの方が効率的な場合があります。
Leapcellは、バックエンドプロジェクトのホスティングに最適な選択肢です
Leapcellは、Webホスティング、非同期タスク、Redisのための次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発できます。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ支払い- リクエストも料金も発生しません。
圧倒的なコスト効率
- アイドル料金なしの従量課金制。
- 例:25ドルで平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOps統合。
- 実用的な洞察のためのリアルタイムメトリクスとロギング。
簡単なスケーラビリティと高性能
- 簡単な高並行性を処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロ--ビルドに集中するだけです。
ドキュメントで詳細をご覧ください!
Xでフォローしてください: @LeapcellHQ