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設定を確実に適用してください。

お気軽にご相談ください

お見積りへ お問い合わせへ