2026年8月18日

2026年8月18日

WordPressのGzip圧縮エラーを解決する方法

はじめに

Google PageSpeed InsightsやGTmetrixで「テキストベースのリソースをgzip圧縮して配信してください」と指摘される・.htaccessにmod_deflateの設定を追加したがレスポンスヘッダーにContent-Encoding: gzipが付かない・WordPressキャッシュプラグインのGzip機能を有効にしてもHTMLが圧縮されない・Cloudflare経由だとGzip設定が無視されているといった問題は、Apacheモジュールの無効化・.htaccessの記述位置の問題・サーバーの種類(Apache/Nginx)に合わない設定が原因です。

症状・原因

  • curl -H "Accept-Encoding: gzip" -I https://example.comでもContent-Encoding: gzipが返らない
  • .htaccessに設定を追加したがmod_deflateまたはmod_gzipがサーバーで無効になっている
  • WordPressのキャッシュプラグインがGzip済みHTMLをさらに圧縮しようとして二重圧縮エラーが発生する
  • 共有ホスティングでは.htaccessのGzip設定が使えず管理画面から設定する必要がある

解決手順

ステップ1:Gzip圧縮の状態を診断する

# WP-CLIでGzip対応を確認
wp eval "
// PHPのzlib出力圧縮確認
echo 'zlib.output_compression: ' . ini_get('zlib.output_compression') . PHP_EOL;
echo 'output_handler: '          . ini_get('output_handler') . PHP_EOL;

// サーバーソフトウェア確認
echo 'Server: ' . (\$_SERVER['SERVER_SOFTWARE'] ?? 'unknown') . PHP_EOL;

// Gzipレスポンス確認
\$response = wp_remote_get(home_url('/'), [
    'headers'   => ['Accept-Encoding' => 'gzip, deflate'],
    'sslverify' => false,
]);
if (!is_wp_error(\$response)) {
    \$encoding = wp_remote_retrieve_header(\$response, 'content-encoding');
    echo 'Content-Encoding: ' . (\$encoding ?: 'none (Gzip not active)') . PHP_EOL;
    echo 'Content-Length: '   . wp_remote_retrieve_header(\$response, 'content-length') . PHP_EOL;
}
"

# mod_deflate が利用可能か確認(Apache)
wp eval "
if (function_exists('apache_get_modules')) {
    \$modules = apache_get_modules();
    echo 'mod_deflate: ' . (in_array('mod_deflate', \$modules) ? 'enabled' : 'DISABLED') . PHP_EOL;
    echo 'mod_gzip: '    . (in_array('mod_gzip',    \$modules) ? 'enabled' : 'not installed') . PHP_EOL;
    echo 'mod_brotli: '  . (in_array('mod_brotli',  \$modules) ? 'enabled' : 'not installed') . PHP_EOL;
} else {
    echo 'apache_get_modules() not available (Nginx or CGI mode)' . PHP_EOL;
}
"

ステップ2:Apache(.htaccess)でGzipを有効化する

# .htaccess: mod_deflate でGzip圧縮を設定(WordPressの# BEGIN WordPressの前に追加)
<IfModule mod_deflate.c>
    # テキストコンテンツを圧縮
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE text/javascript
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE application/javascript
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/json
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom+xml
    AddOutputFilterByType DEFLATE image/svg+xml
    AddOutputFilterByType DEFLATE font/woff2
    AddOutputFilterByType DEFLATE font/woff

    # 古いブラウザへの対応
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html

    # プロキシキャッシュ対応
    Header append Vary Accept-Encoding
</IfModule>

# Brotli圧縮(mod_brotliが利用可能な場合)
<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript
    BrotliCompressionQuality 6
</IfModule>

ステップ3:Nginxでgzip設定を行う

# nginx.conf または /etc/nginx/conf.d/gzip.conf
# WordPressサーバーのgzip設定

gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/json
    application/javascript
    application/x-javascript
    application/xml
    application/rss+xml
    application/atom+xml
    image/svg+xml
    font/woff2
    font/woff;
gzip_min_length 1024;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";

# Brotli(ngx_brotliモジュールが必要)
# brotli on;
# brotli_comp_level 6;
# brotli_types text/plain text/css application/javascript application/json image/svg+xml;
// wp-config.php: PHPレベルのgzip(最終手段)
// mod_deflateが使えない場合のみ使用(二重圧縮に注意)
if (!ini_get('zlib.output_compression') && !headers_sent()) {
    ini_set('zlib.output_compression', '4096');
}

ステップ4:WordPressのPHP出力圧縮を設定する

// functions.php: PHP出力バッファリングを使ったGzip

// ① ob_gzhandler を使った圧縮(mod_deflateがない場合)
add_action('init', function(): void {
    // 既にgzip済みの場合はスキップ
    if (
        headers_sent()
        || ini_get('zlib.output_compression')
        || (defined('DOING_AJAX') && DOING_AJAX)
    ) {
        return;
    }

    // クライアントがgzipをサポートしているか確認
    $accept_encoding = $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '';
    if (str_contains($accept_encoding, 'gzip') && function_exists('ob_gzhandler')) {
        ob_start('ob_gzhandler');
    }
});

// ② Gzip後のコンテンツ長をヘッダーに追加
add_action('send_headers', function(): void {
    if (!is_admin() && !headers_sent()) {
        header('Vary: Accept-Encoding');
    }
});

ステップ5:Gzip圧縮の効果を測定・検証する

# Gzip圧縮率を確認
wp eval "
\$url = home_url('/');

// 非圧縮サイズ
\$response_plain = wp_remote_get(\$url, ['sslverify' => false]);
\$plain_size = strlen(wp_remote_retrieve_body(\$response_plain));

// 圧縮サイズ
\$response_gzip = wp_remote_get(\$url, [
    'headers'   => ['Accept-Encoding' => 'gzip'],
    'sslverify' => false,
]);
\$gzip_size     = (int) wp_remote_retrieve_header(\$response_gzip, 'content-length');
\$encoding      = wp_remote_retrieve_header(\$response_gzip, 'content-encoding');

echo 'Plain size: '   . number_format(\$plain_size) . ' bytes' . PHP_EOL;
echo 'Gzip size: '    . number_format(\$gzip_size)  . ' bytes' . PHP_EOL;
echo 'Compression: '  . round((1 - \$gzip_size / \$plain_size) * 100, 1) . '%' . PHP_EOL;
echo 'Encoding: '     . (\$encoding ?: 'none') . PHP_EOL;
"

# 静的ファイルのGzip確認
wp eval "
\$css_url  = get_theme_file_uri('style.css');
\$response = wp_remote_head(\$css_url, [
    'headers'   => ['Accept-Encoding' => 'gzip'],
    'sslverify' => false,
]);
if (!is_wp_error(\$response)) {
    echo 'CSS Encoding: ' . (wp_remote_retrieve_header(\$response, 'content-encoding') ?: 'none') . PHP_EOL;
    echo 'Cache-Control: ' . wp_remote_retrieve_header(\$response, 'cache-control') . PHP_EOL;
}
"

注意事項

  • zlib.output_compressionとWordPressキャッシュプラグインのGzip機能を同時に有効にすると、二重圧縮が発生してページが正常に表示されなくなります。どちらか一方に統一してください
  • 画像(JPEG、PNG、WebP)・PDF・動画ファイルはすでに圧縮済みのため、Gzip圧縮対象に含めないでください。圧縮してもファイルサイズはほとんど変わらず処理時間が無駄になります
  • Cloudflareを使用している場合は、Cloudflare側でGzip/Brotliが自動的に処理されます。オリジンサーバーのGzip設定と重複することがありますが、Cloudflareが適切に処理するため通常は問題ありません

まとめ

WordPress Gzip圧縮エラーの解決は①Content-Encodingレスポンスヘッダー確認・apache_get_modules()でmod_deflateの有効状態チェック・zlib.output_compression設定確認、②.htaccessブロックを追加・HTML/CSS/JS/JSON/SVG/フォントを圧縮対象に・Header append Vary Accept-Encodingでプロキシキャッシュ対応、③Nginxはgzip ongzip_typesに必要なMIMEタイプを列挙・gzip_comp_level 6でバランスを調整、④mod_deflateが使えない場合のみPHPのob_gzhandlerを使用・zlib.output_compressionで出力圧縮を有効化、⑤圧縮前後のサイズ比較で圧縮率を確認・70〜80%の削減が理想の手順で解決します。

お気軽にご相談ください

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