// ── Tell LiteSpeed to never lazy-load WooCommerce product images ────────────── add_filter('litespeed_media_lazy_img_cls_excludes', function($excludes) { if (!is_array($excludes)) $excludes = []; $excludes[] = 'woo-entry-image-main'; $excludes[] = 'wp-post-image'; return $excludes; }); // ── Remove lazy loading from first WooCommerce product image ────────────────── add_action('template_redirect', function() { ob_start(function($html) { static $done = false; if ($done) return $html; $html = preg_replace_callback( '/]*class="[^"]*woo-entry-image-main[^"]*"[^>]*)>/i', function($m) use (&$done) { if ($done) return $m[0]; $attrs = $m[1]; $attrs = str_replace(' loading="lazy"', '', $attrs); $attrs = str_replace(" loading='lazy'", '', $attrs); $attrs = preg_replace('/\s*data-lazyloaded="[^"]*"/', '', $attrs); if (strpos($attrs, 'fetchpriority') === false) { $attrs .= ' fetchpriority="high"'; } $done = true; return ''; }, $html ); return $html; }); }, 1); // ── Remove lazy loading from first WooCommerce product image ────────────────── add_action('template_redirect', function() { ob_start(function($html) { static $done = false; if ($done) return $html; $html = preg_replace_callback( '/]*class="[^"]*woo-entry-image-main[^"]*"[^>]*)>/i', function($m) use (&$done) { if ($done) return $m[0]; $attrs = $m[1]; $attrs = str_replace(' loading="lazy"', '', $attrs); $attrs = str_replace(" loading='lazy'", '', $attrs); $attrs = preg_replace('/\s*data-lazyloaded="[^"]*"/', '', $attrs); if (strpos($attrs, 'fetchpriority') === false) { $attrs .= ' fetchpriority="high"'; } $done = true; return ''; }, $html ); return $html; }); }, 1); // ── Fix lazy loading v2 — simpler regex ─────────────────────────────────────── add_action('template_redirect', function() { ob_start(function($html) { // Remove first occurrence of loading="lazy" from woo-entry-image-main $count = 0; return preg_replace_callback( '/]*woo-entry-image-main[^>]*>/i', function($m) use (&$count) { if ($count > 0) return $m[0]; $tag = preg_replace('/\s+loading=["\']lazy["\']/i', '', $m[0]); $tag = str_replace(' decoding="async"', ' decoding="async" fetchpriority="high"', $tag); $count++; return $tag; }, $html ); }); }, 2); // ── Remove lazy from first product image using WP filter ───────────────────── add_filter('wp_get_attachment_image_attributes', function($attr, $attachment, $size) { static $count = 0; if ($count > 0) return $attr; // Check if this is a WooCommerce product thumbnail if (isset($attr['class']) && strpos($attr['class'], 'woo-entry-image-main') !== false) { $attr['loading'] = 'eager'; $attr['fetchpriority'] = 'high'; $count++; } return $attr; }, 99, 3); // ── WooCommerce specific image eager loading ────────────────────────────────── add_filter('woocommerce_product_loop_start', function($html) { // Flag that we're in the first product loop global $abh_first_product_done; $abh_first_product_done = false; return $html; }); add_filter('woocommerce_thumbnail_size', function($size) { global $abh_first_product_done; if (!$abh_first_product_done) { add_filter('wp_get_attachment_image_attributes', function($attr) { global $abh_first_product_done; if (!$abh_first_product_done) { $attr['loading'] = 'eager'; $attr['fetchpriority'] = 'high'; $abh_first_product_done = true; } return $attr; }, 999); } return $size; }); // ── Fix first product image loading via wp_get_attachment_image_attributes ──── remove_all_filters('wp_get_attachment_image_attributes', 999); add_filter('wp_get_attachment_image_attributes', function($attr, $attachment, $size) { static $fixed = false; if ($fixed) return $attr; $class = isset($attr['class']) ? $attr['class'] : ''; if (strpos($class, 'woo-entry-image-main') !== false) { $attr['loading'] = 'eager'; $attr['fetchpriority'] = 'high'; $fixed = true; } return $attr; }, 9999, 3);