Nginxで静的アセットをキャッシュしてサイトを高速化する方法

Web2026-09-21TryQuickToolBox

静的アセットのキャッシュが重要な理由

ユーザーがあなたのウェブサイトを訪れるたびに、ブラウザはCSSファイル、JavaScript、画像、フォントなど、数十の静的アセットをリクエストします。適切なキャッシュがなければ、各リクエストがサーバーに到達し、読み込み時間と帯域幅の使用量が増加します。高性能ウェブサーバーであるNginxは、ブラウザにこれらのアセットをローカルにキャッシュするよう指示し、サーバー側でもキャッシュすることで、これを劇的に改善できます。

このガイドでは、Nginxを設定して静的アセットを効果的にキャッシュし、レイテンシとサーバー負荷を削減する方法を学びます。

ブラウザキャッシュとサーバー側キャッシュの理解

ここで関連するキャッシュには主に2つの種類があります:

どちらもパフォーマンスにとって重要です。両方について説明します。

ステップ1: Expiresヘッダーでブラウザキャッシュを設定する

ブラウザキャッシュを有効にする最も簡単な方法は、Nginx設定にexpiresディレクティブを追加することです。これによりExpiresとCache-Controlヘッダーが設定されます。

サイトの設定ファイル(例: /etc/nginx/sites-available/example.com)を開き、静的アセット用のlocationブロックを追加します:

location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}

これにより、ブラウザはこれらのファイルを1年間キャッシュします。immutableディレクティブはファイルが決して変更されないことを示すため、ブラウザは再読み込み時にも再検証を行いません。

ベストプラクティス: バージョン付きのファイル名(例: style.abc123.css)を使用して、キャッシュを壊さずにアセットを更新できるようにします。ファイルが変更されるとファイル名も変わり、ブラウザは新しいバージョンを取得します。

ステップ2: プロキシキャッシュでサーバー側キャッシュを有効にする

Nginxの背後でアプリケーションサーバー(Node.js、Python、PHPなど)を実行している場合、Nginxで静的レスポンスをキャッシュしてバックエンドへのリクエストを削減できます。

まず、nginx.confのhttpブロックでキャッシュパスを定義します:

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=static_cache:10m max_size=1g inactive=60m use_temp_path=off;

次に、serverブロックでこれを使用します:

location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
    proxy_cache static_cache;
    proxy_cache_valid 200 302 1y;
    proxy_cache_valid 404 1m;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_cache_lock on;
    add_header X-Cache-Status $upstream_cache_status;
    proxy_pass http://backend;
}

これにより、成功したレスポンスが1年間キャッシュされ、バックエンドがダウンしている場合は古いコンテンツが配信されます。X-Cache-Statusヘッダーはデバッグに役立ちます(HIT、MISSなど)。

ステップ3: 圧縮とHTTP/2で最適化する

キャッシュはリクエストを削減しますが、gzip圧縮とHTTP/2を有効にすることで転送をさらに高速化できます。

nginx.confでgzipを有効にします:

gzip on;
gzip_types text/css application/javascript image/svg+xml;
gzip_min_length 1000;

HTTP/2はリクエストを多重化し、listenディレクティブにhttp2を追加することで有効になります:

listen 443 ssl http2;

注: HTTP/2にはHTTPSが必要です。まだTLSを設定していない場合は、HTTPSとTLSの仕組みに関するガイドをご覧ください。

比較: Cache-Controlディレクティブ

ディレクティブ 意味 推奨用途
public レスポンスは任意のキャッシュでキャッシュ可能 静的アセット
private レスポンスは単一ユーザー用 ユーザー固有のデータ
no-cache サーバーで再検証が必要 HTMLページ
no-store キャッシュしない 機密データ
immutable コンテンツは変更されない バージョン付きアセット

ステップ4: テストと検証

変更を適用したら、Nginxを再読み込みします: sudo nginx -s reload。次にcurlでテストします:

curl -I https://example.com/style.css

Cache-ControlとExpiresヘッダーを確認します。ブラウザのDevTools(Networkタブ)を使用して、アセットがキャッシュから配信されているか(ステータス200または304)を確認することもできます。

サーバー側キャッシュについては、X-Cache-Statusヘッダーを監視します。

よくある落とし穴とベストプラクティス

FAQ

アセットがキャッシュされているかどうかを確認するには?

curl -IまたはブラウザのDevToolsでレスポンスヘッダーを確認します。Cache-Control: public, max-age=31536000とExpiresヘッダーを探します。DevToolsでは、キャッシュされたアセットのSize列に「(from disk cache)」と表示されます。

expiresとCache-Controlの違いは何ですか?

expiresは絶対日付を設定し、Cache-Controlは相対秒数を使用します。最新のブラウザではCache-Controlが優先されます。Nginxのexpiresディレクティブは互換性のために両方を設定します。

動的コンテンツをキャッシュできますか?

はい、ただし注意が必要です。短いTTLでproxy_cacheを使用し、Cookieやヘッダーに基づくキャッシュキーを検討してください。ユーザー固有のコンテンツにはprivateを使用するか、キャッシュを避けてください。

TryQuickToolBoxでワークフローを加速する

サイトのパフォーマンスを最適化する際に、画像やPDFを圧縮する必要があるかもしれません。品質を損なわずに画像サイズを削減するImage Compressorを試して、Nginxキャッシュ戦略を補完しましょう。