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 );
}