2026年8月17日

2026年8月17日

Smush(画像圧縮プラグイン)のエラーを解決する方法

はじめに

WP Smushで画像の一括最適化が途中でタイムアウトする・WebP変換が有効なのにブラウザにWebPが配信されない・CDN機能を有効にすると一部画像が404になる・最適化済みの画像を再圧縮したい問題は、サーバーのGD/Imagick設定・.htaccessのWebPリダイレクトルール・Smushのバッチサイズが原因です。

症状・原因

  • 「一括最適化」を実行すると50〜100枚あたりで処理が止まり「タイムアウト」と表示される
  • WebP変換を有効にしたがPNGやJPEGがそのまま配信されている
  • Smush CDNを有効にすると特定の画像が表示されない
  • 一度最適化した画像をより高い圧縮率で再最適化したい

解決手順

ステップ1:Smushの状態を確認する

# Smushの設定と最適化状況を確認
wp eval "
// Smushバージョン確認
if (defined('WP_SMUSH_VERSION')) {
    echo 'Smush version: ' . WP_SMUSH_VERSION . PHP_EOL;
    echo 'Smush PRO: ' . (defined('WP_SMUSHIT_DIR') ? 'check plugin files' : 'unknown') . PHP_EOL;
}

// Smush設定を確認
\$settings = get_option('wp-smush-settings', []);
echo 'Auto smush: '    . (\$settings['auto']    ?? '0') . PHP_EOL;
echo 'WebP enabled: '  . (\$settings['webp']    ?? '0') . PHP_EOL;
echo 'CDN enabled: '   . (\$settings['cdn']     ?? '0') . PHP_EOL;
echo 'Lazy load: '     . (\$settings['lazy_load'] ?? '0') . PHP_EOL;

// 最適化統計を確認
\$stats = get_option('smush_image_count', []);
echo 'Total optimized: ' . (\$stats['total'] ?? 0) . PHP_EOL;
echo 'Total savings: '   . (\$stats['bytes'] ?? 0) . ' bytes' . PHP_EOL;

// GD/Imagick確認
echo 'GD: '       . (function_exists('gd_info') ? 'available' : 'not available') . PHP_EOL;
echo 'Imagick: '  . (class_exists('Imagick') ? 'available' : 'not available') . PHP_EOL;
"

# WebPサポートの確認
wp eval "
\$img = imagecreatetruecolor(1, 1);
echo 'WebP support: ' . (function_exists('imagewebp') ? 'yes' : 'no') . PHP_EOL;
imagedestroy(\$img);
"

ステップ2:一括最適化のタイムアウトを修正する

// functions.php: Smush最適化のカスタマイズ

// ① バッチサイズを小さくしてタイムアウトを防ぐ
add_filter('wp_smush_bulk_count', function(int $count): int {
    return 5; // デフォルト10から5に減らす
});

// ② 最適化のタイムアウト時間を延長
add_filter('wp_smush_timeout', function(int $timeout): int {
    return 60; // 60秒(デフォルトは30秒)
});

// ③ 特定サイズの画像をSmushからスキップ
add_filter('smush_skip_image_size', function(bool $skip, string $size): bool {
    // サムネイルのみ最適化、大きなサイズはスキップ
    $skip_sizes = ['1536x1536', '2048x2048', 'full'];
    return in_array($size, $skip_sizes, true);
}, 10, 2);

// ④ 特定の添付ファイルをSmushから除外
add_filter('smush_skip_image', function(bool $skip, int $attachment_id): bool {
    // SVGファイルはスキップ
    if (get_post_mime_type($attachment_id) === 'image/svg+xml') {
        return true;
    }
    // 特定カテゴリーの商品画像はスキップ
    $post_parent = get_post_field('post_parent', $attachment_id);
    if ($post_parent && get_post_type($post_parent) === 'product') {
        // WooCommerce商品画像は独自最適化
        return false;
    }
    return $skip;
}, 10, 2);

ステップ3:WebP配信を設定する

// functions.php: WebP設定

// ① srcsetにWebPを追加しないサイズを指定
add_filter('smush_skip_adding_srcset', function(bool $skip, array $size_data): bool {
    // 幅150px以下のサムネイルはWebP srcsetを追加しない
    if (isset($size_data['width']) && $size_data['width'] <= 150) {
        return true;
    }
    return $skip;
}, 10, 2);

// ② WebP画像のパスを確認するユーティリティ
function check_webp_exists(int $attachment_id): array {
    $file   = get_attached_file($attachment_id);
    $webp   = $file . '.webp';
    $result = [
        'original' => $file,
        'webp'     => $webp,
        'exists'   => file_exists($webp),
        'size'     => file_exists($webp) ? filesize($webp) : 0,
    ];
    return $result;
}
# .htaccess: WebP自動配信ルール(Apacheサーバー)
<IfModule mod_rewrite.c>
  RewriteEngine On

  # WebPサポートがある場合、JPG/PNGをWebPに置き換え
  RewriteCond %{HTTP_ACCEPT} image/webp
  RewriteCond %{REQUEST_FILENAME} \.(jpe?g|png)$
  RewriteCond %{REQUEST_FILENAME}\.webp -f
  RewriteRule ^ %{REQUEST_URI}.webp [L,T=image/webp]

  <IfModule mod_headers.c>
    Header append Vary Accept env=REDIRECT_accept
  </IfModule>
</IfModule>

ステップ4:Smush CDNを設定する

// functions.php: Smush CDNカスタマイズ

// ① CDNから除外するURLパターンを追加
add_filter('smush_cdn_skip_url', function(bool $skip, string $url): bool {
    // 管理画面の画像はCDN経由にしない
    if (str_contains($url, '/wp-admin/')) return true;
    // プレースホルダー画像はCDN経由にしない
    if (str_contains($url, 'placeholder')) return true;
    return $skip;
}, 10, 2);

// ② CDNのキャッシュをプログラムでパージ
function smush_cdn_purge_attachment(int $attachment_id): void {
    $url = wp_get_attachment_url($attachment_id);
    if (!$url) return;

    // Smush CDN APIでキャッシュパージ
    do_action('wp_smush_cdn_purge', $url);
    error_log('[Smush] CDN cache purged for: ' . $url);
}

// ③ 画像更新時に自動でCDNパージ
add_action('attachment_updated', function(int $id): void {
    smush_cdn_purge_attachment($id);
});

ステップ5:最適化データをリセットして再圧縮する

# 最適化データをリセットして再最適化
wp eval "
// 全画像の最適化データをリセット
\$attachments = get_posts([
    'post_type'      => 'attachment',
    'post_mime_type' => ['image/jpeg', 'image/png'],
    'posts_per_page' => -1,
    'fields'         => 'ids',
]);

echo 'Total images: ' . count(\$attachments) . PHP_EOL;

// 最適化メタデータをクリア(再最適化可能にする)
\$reset_count = 0;
foreach (\$attachments as \$id) {
    \$smush_data = get_post_meta(\$id, 'wp-smpro-smush-data', true);
    if (\$smush_data) {
        delete_post_meta(\$id, 'wp-smpro-smush-data');
        delete_post_meta(\$id, 'wp-smush-data');
        \$reset_count++;
    }
}
echo 'Reset: ' . \$reset_count . ' images' . PHP_EOL;
"

# WP-CLIで最適化を実行(タイムアウト対策)
wp smush optimize --all --defer
// functions.php: 最適化完了フック

// ① 画像最適化完了時にログ
add_action('wp_smush_image_optimised', function(int $attachment_id, array $data): void {
    $savings = $data['stats']['bytes'] ?? 0;
    error_log(sprintf('[Smush] Optimized %d: saved %s bytes', $attachment_id, $savings));
}, 10, 2);

// ② 自動最適化の対象をJPEGのみに限定
add_filter('wp_smush_auto_smush', function(bool $auto, string $mime): bool {
    return $auto && $mime === 'image/jpeg'; // JPEGのみ自動最適化
}, 10, 2);

注意事項

  • WebP変換はサーバーのGD拡張またはImagickがWebPをサポートしている必要があります。php -r "echo function_exists('imagewebp') ? 'yes' : 'no';" で確認してください。対応していない場合はサーバー管理者にGD拡張の再コンパイルを依頼してください
  • Smush CDNはMUSEサーバーを経由するため、アップロードした画像が海外サーバーにキャッシュされます。個人情報を含む画像(ユーザーの写真など)をCDN経由で配信することがプライバシーポリシー上問題ないか確認してください
  • 最適化データをリセットすると、次回の一括最適化で全画像が再処理されます。サイト規模が大きい場合はサーバー負荷が高くなるため、夜間や低トラフィック時に実行してください

まとめ

Smush修復は①wp-smush-settingsオプション確認・GD/Imagickのサポート確認、②wp_smush_bulk_countフィルターでバッチサイズを5に削減・smush_skip_image_sizeで大サイズをスキップしてタイムアウト防止、③smush_skip_adding_srcsetフィルターでWebP srcsetを制御・.htaccessにWebP自動配信ルールを追加、④smush_cdn_skip_urlフィルターでCDN除外URLを設定・attachment_updatedフックでCDNキャッシュを自動パージ、⑤wp-smush-dataメタを削除して再最適化可能状態にリセット・wp smush optimize --allでWP-CLI実行する手順で解決します。

お気軽にご相談ください

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