Commit 7bb4d63caf for woocommerce

commit 7bb4d63caf8394666fafa6fd98fbf94ee686b399
Author: Deepak Lalwani <deepak.lalwani81@gmail.com>
Date:   Wed Jan 21 15:45:36 2026 +0530

    Add lazy loading attribute to product image (#62829)

    * Add lazy loading attribute to product image

    * Add changelog entry

    * Harden woocommerce_product_image_loading_attr output and make the filter context-aware.

    * Remove extra filter parameters and update filter documentation

    ---------

    Co-authored-by: Karol Manijak <20098064+kmanijak@users.noreply.github.com>

diff --git a/plugins/woocommerce/changelog/enhancement-42390-lazy-load-product-image b/plugins/woocommerce/changelog/enhancement-42390-lazy-load-product-image
new file mode 100644
index 0000000000..79241beb42
--- /dev/null
+++ b/plugins/woocommerce/changelog/enhancement-42390-lazy-load-product-image
@@ -0,0 +1,6 @@
+Significance: minor
+Type: enhancement
+
+Add lazy loading attribute to product image block.
+
+Introduce a new filter `woocommerce_product_image_loading_attr` to modify the loading attribute.
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/ProductImage.php b/plugins/woocommerce/src/Blocks/BlockTypes/ProductImage.php
index e28350ea64..f873ad787b 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/ProductImage.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/ProductImage.php
@@ -177,6 +177,29 @@ class ProductImage extends AbstractBlock {

 		$alt_text = get_post_meta( $target_image_id, '_wp_attachment_image_alt', true );

+		/**
+		 * Filters the loading attribute for product images.
+		 *
+		 * Allowed values are 'lazy', 'eager', and 'auto'. Any other value will result in default browser behavior.
+		 *
+		 * @since 10.6.0
+		 *
+		 * @param string $loading_attr The loading attribute. Default 'lazy'.
+		 * @param int    $image_id     Target image ID.
+		 */
+		$loading_attr = apply_filters(
+			'woocommerce_product_image_loading_attr',
+			'lazy',
+			$target_image_id,
+		);
+
+		$loading_attr    = is_string( $loading_attr ) ? strtolower( trim( $loading_attr ) ) : '';
+		$allowed_loading = array( 'lazy', 'eager', 'auto' );
+
+		if ( ! in_array( $loading_attr, $allowed_loading, true ) ) {
+			$loading_attr = '';
+		}
+
 		$attr = array(
 			'alt'           => empty( $alt_text ) ? $product->get_title() : $alt_text,
 			'data-testid'   => 'product-image',
@@ -184,6 +207,10 @@ class ProductImage extends AbstractBlock {
 			'style'         => $image_style,
 		);

+		if ( ! empty( $loading_attr ) ) {
+			$attr['loading'] = $loading_attr;
+		}
+
 		return $provided_image_id_is_valid ? wp_get_attachment_image( $image_id, $image_size, false, $attr ) : $product->get_image( $image_size, $attr );
 	}