2026年5月20日
2026年5月20日
WordPressのCloudflareとキャッシュプラグインの競合を解決する方法
はじめに
CloudflareとWordPressのキャッシュプラグインは、それぞれ独立したキャッシュレイヤーを持ちます。適切に設定しないと古いコンテンツが表示され続けたり、管理画面が壊れたりする問題が発生します。それぞれの役割を理解して正しく連携させましょう。
症状・原因
- 記事を更新しても古い内容が表示される
- 管理画面にログインできない・レイアウトが崩れる
- キャッシュをクリアしても変化がない
- CloudflareのダッシュボードでBYPASSがずっと表示される
解決手順
ステップ1:キャッシュの役割分担を理解する
キャッシュの階層構造:
┌─────────────────────────────────────────┐
│ ① Cloudflare CDN(エッジキャッシュ) │ ← 世界中のエッジサーバー
│ 静的ファイル・HTML(設定次第) │
├─────────────────────────────────────────┤
│ ② サーバーキャッシュ(FastCGI/Nginx) │ ← オリジンサーバー
│ PHPの実行結果をHTMLで保持 │
├─────────────────────────────────────────┤
│ ③ WordPressキャッシュプラグイン │ ← WordPress層
│ WP Super Cache・W3 Total Cache等 │
├─────────────────────────────────────────┤
│ ④ オブジェクトキャッシュ(Redis/Memcached)│ ← DB層
│ DBクエリ結果をメモリに保持 │
└─────────────────────────────────────────┘
推奨構成:
- CloudflareはCSSU/JS/画像のみキャッシュ(HTMLはバイパス)
- HTMLのキャッシュはサーバーキャッシュかWPプラグインに任せる
- 両方でHTMLをキャッシュすると二重管理になり混乱の元
ステップ2:CloudflareでHTMLをキャッシュしない設定にする
Cloudflareダッシュボード → キャッシュ → キャッシュルール
ルール: HTMLをキャッシュしない
条件: ファイル拡張子 not in [jpg, jpeg, png, gif, webp, css, js, woff2, svg, ico]
設定: キャッシュ対象外
OR
ルール: 静的ファイルのみキャッシュ
条件: ファイル拡張子 in [jpg, jpeg, png, gif, webp, css, js, woff2, svg, ico, pdf]
設定: キャッシュあり + エッジTTL: 7日
ステップ3:W3 Total Cache と Cloudflare を連携する
// W3 Total Cache の Cloudflare 連携設定
// WordPress管理画面 → パフォーマンス → 全般設定
// Cloudflare設定:
// - APIキー: Cloudflare API トークン
// - ゾーンID: CloudflareダッシュボードのゾーンID
// - メールアドレス: Cloudflareアカウントのメール
// 設定後、投稿更新時に自動的にCloudflareキャッシュをパージ
// functions.php: キャッシュプラグインとCloudflareの手動連携
function mytheme_clear_all_caches(int $post_id): void {
if (wp_is_post_revision($post_id)) {
return;
}
// W3 Total Cache
if (function_exists('w3tc_flush_post')) {
w3tc_flush_post($post_id);
}
// WP Super Cache
if (function_exists('wp_cache_post_change')) {
wp_cache_post_change($post_id);
}
// LiteSpeed Cache
if (class_exists('LiteSpeed_Cache_API')) {
LiteSpeed_Cache_API::purge(LiteSpeed_Cache_API::TYPE_POST, $post_id);
}
// WP Rocket
if (function_exists('rocket_clean_post')) {
rocket_clean_post($post_id);
}
// Cloudflare APIでHTMLもパージ(必要な場合)
mytheme_cloudflare_purge_url(get_permalink($post_id));
mytheme_cloudflare_purge_url(home_url('/'));
}
add_action('save_post', 'mytheme_clear_all_caches');
function mytheme_cloudflare_purge_url(string $url): void {
$zone_id = defined('CF_ZONE_ID') ? CF_ZONE_ID : '';
$api_key = defined('CF_API_KEY') ? CF_API_KEY : '';
if (!$zone_id || !$api_key) {
return;
}
wp_remote_post(
"https://api.cloudflare.com/client/v4/zones/{$zone_id}/purge_cache",
[
'headers' => [
'Authorization' => 'Bearer ' . $api_key,
'Content-Type' => 'application/json',
],
'body' => wp_json_encode(['files' => [$url]]),
'timeout' => 10,
]
);
}
ステップ4:管理画面のキャッシュ問題を解決する
// functions.php: 管理画面・ログイン中はキャッシュ無効化ヘッダーを送信
function mytheme_no_cache_for_logged_in(): void {
if (is_user_logged_in() || is_admin()) {
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
header('Pragma: no-cache');
header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
}
}
add_action('send_headers', 'mytheme_no_cache_for_logged_in');
# .htaccess: ログインCookieがある場合はCloudflareキャッシュをバイパス
# (Cloudflareの設定と組み合わせて使用)
<IfModule mod_headers.c>
# WordPressのログインCookieがある場合はキャッシュしない
# Cloudflareはこのヘッダーを見てキャッシュするかどうかを判断
Header always set Cache-Control "no-store" "expr=%{HTTP_COOKIE} =~ /wordpress_logged_in/"
</IfModule>
ステップ5:LiteSpeed CacheとCloudflareの最適な組み合わせ
LiteSpeed Cache(推奨)+ Cloudflare の組み合わせ:
LiteSpeed Cache側:
- HTMLキャッシュ: 有効(LSサーバーが高速処理)
- CDN: Cloudflareを指定
- 画像最適化: WebP変換
- Cloudflareとの連携: API経由で自動パージ
Cloudflare側:
- HTMLはキャッシュしない(LSCが担当)
- 静的ファイルのみキャッシュ
- Auto Minify: 無効(LSCと競合する場合)
この構成で最大のパフォーマンスを発揮する
注意事項
- Cloudflareの「開発モード」を有効にするとすべてのキャッシュが一時的に無効になります。問題の切り分けに使いますが、3時間で自動解除されます
Cache-Control: no-storeヘッダーを送信しているページはCloudflareでもキャッシュされません。プラグインがこのヘッダーを正しく出力しているか確認してください- CloudflareのオレンジクラウドをグレーにするとCDNが無効になり、サーバーのIPが直接公開されます
まとめ
CloudflareはCSSS/JS/画像のキャッシュに特化し、HTMLはサーバーキャッシュかLiteSpeed Cacheに任せるのが最もシンプルな構成です。save_post フックで全キャッシュを一括クリアする関数を用意しておくと、更新後の古いコンテンツ問題を予防できます。管理画面にはCloudflareのBYPASS設定を確実に適用してください。