なぜセキュリティ設定とキャッシュをセットで管理するのか
HTTPS 化とキャッシュ設定はセットで行うのが効率的。どちらも .htaccess で管理できるため、一括設定することでメンテナンスコストを下げられる。
また、セキュリティプラグイン(Wordfence 等)はリクエストごとにスキャン処理を行うため、サイトのパフォーマンスに影響する場合がある。キャッシュとパフォーマンス最適化によってその「重さ」を相殺できる。
Gzip 圧縮(mod_deflate)
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/css
AddOutputFilterByType DEFLATE application/javascript application/json
AddOutputFilterByType DEFLATE application/xml text/xml image/svg+xml
AddOutputFilterByType DEFLATE font/woff font/woff2
</IfModule>
役割と効果
テキストベースのファイル(HTML・CSS・JavaScript・JSON など)をサーバー側で圧縮してからブラウザに送信する。同じコンテンツでもデータ量を大幅に削減でき、ページの読み込み速度が向上する。
対象 MIME タイプの選び方
| MIME タイプ | 対応ファイル | 圧縮効果 |
|---|---|---|
text/html |
HTML ページ | 高(テキストベース) |
text/css |
スタイルシート | 高 |
application/javascript |
JavaScript | 高 |
application/json |
JSON データ | 高 |
image/svg+xml |
SVG 画像 | 高(XML テキスト) |
font/woff2 |
Web フォント | 低(すでに圧縮済み) |
JPEG・PNG・WebP などの画像ファイルはすでに圧縮されているため、Gzip の対象にする必要はない。圧縮しても効果が薄く、CPU 負荷だけ増える。
ブラウザキャッシュ(Cache-Control)
<IfModule mod_headers.c>
# 画像・フォント・アイコン(1年キャッシュ + immutable)
<FilesMatch "\.(ico|jpg|jpeg|png|gif|webp|svg|woff|woff2|ttf)$">
Header always set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
# CSS・JavaScript(1年キャッシュ + immutable)
<FilesMatch "\.(css|js)$">
Header always set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
# HTML・JSON・XML(キャッシュしない)
<FilesMatch "\.(html|htm|json|xml)$">
Header always set Cache-Control "no-store, no-cache, must-revalidate"
</FilesMatch>
</IfModule>
ファイル種類ごとのキャッシュ有効期限
| ファイル種類 | 推奨設定 | 理由 |
|---|---|---|
| 画像・フォント・CSS・JS | 1年(31536000秒) | 更新頻度が低い静的ファイル |
| HTML・JSON・XML | キャッシュしない | WordPress が動的に生成するコンテンツ |
immutable フラグの意味
max-age の期限内はサーバーへの再検証リクエスト(条件付き
GET)自体を省略する指示。ブラウザが「このファイルは期限内に変わらないと保証されている」とみなし、再アクセス時にサーバーへ問い合わせず即座にキャッシュを返す。
immutableを使う場合は、CSS・JS のファイル名にバージョン番号やハッシュを含める(キャッシュバスティング)ことが前提。WordPress プラグイン・テーマは通常クエリ文字列(?ver=6.0)でバージョン管理しているため問題ない。
HTML / JSON / XML をキャッシュしない理由
WordPress が生成する HTML
は投稿・コメント・プラグインの設定によって毎回変わりうる動的コンテンツ。これをキャッシュすると古いコンテンツが表示され続けるため、no-store
で完全にキャッシュを無効化する。
ETag の無効化
FileETag None
役割とメリット
ETag はファイルの変更を検出するための識別子。Cache-Control で有効期限を設定している場合、ETag による再検証は冗長になる。
ETag を無効化する主なメリットは以下の通り。
- 冗長な
If-None-Matchリクエストがなくなりサーバー負荷が下がる - 複数のウェブサーバーで構成される環境(ロードバランサー等)では、サーバーごとに ETag の値が異なるため正しく機能しないケースがある。これを回避できる
MIME タイプの追加(mime_module)
<IfModule mime_module>
AddType image/x-icon .ico
AddType image/svg+xml .svg
AddType font/woff .woff
AddType font/woff2 .woff2
AddType application/font-ttf .ttf
</IfModule>
役割
Apache がファイルの種類を正しく識別し、ブラウザに適切な Content-Type ヘッダーを返すための設定。MIME
タイプが正しくないと以下の問題が起きる。
- ブラウザがフォントファイルをテキストとして扱い、読み込みに失敗する
- SVG が画像として表示されない
- ブラウザが CORS エラーを起こす(特に Web フォント)
古いバージョンの Apache では .woff2 や .webp が未定義の場合があるため、明示的に追加しておくと安全。
Keep-Alive について
役割
HTTP の持続接続(Keep-Alive)は、1 回の TCP 接続で複数のリクエストを処理する機能。通常、ページを表示するには HTML・CSS・JS・画像など複数のファイルをそれぞれ個別の TCP 接続で取得する。Keep-Alive を使うと接続の確立・切断(TCP ハンドシェイク)のオーバーヘッドを削減してページの表示速度を向上させる。
.htaccess では制御できない
Keep-Alive の有効・無効は Apache のサーバー設定(httpd.conf や apache2.conf)で決まる。Connection はホップバイホップヘッダーであるため、.htaccess から Header always set Connection "keep-alive" を指定しても Keep-Alive を有効化する効果はない。
サーバー設定で制御する場合のディレクティブ例:
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5
レンタルサーバー(XServer 等)では Keep-Alive がデフォルトで有効になっている場合がほとんどのため、個別の設定は不要。
HTTP/2 以降では接続の多重化が標準機能として実装されているため、Keep-Alive の設定は主に HTTP/1.1 接続にのみ影響する。