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実行する手順で解決します。