Commit d8433b89af6 for woocommerce
commit d8433b89af6ab252f76416dd714e7b6486f231db
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Mon Apr 13 16:30:48 2026 +0200
[Performance]: Reduce the number of SQLs required to populate cart data in StoreApi (#64088)
Additional cache priming for gallery images, options cache for StoreAPI cart data, and transients cache priming for variable product stores.
diff --git a/plugins/woocommerce/changelog/performance-cart-checkout-cache-priming b/plugins/woocommerce/changelog/performance-cart-checkout-cache-priming
new file mode 100644
index 00000000000..2b1bf67a1cb
--- /dev/null
+++ b/plugins/woocommerce/changelog/performance-cart-checkout-cache-priming
@@ -0,0 +1,4 @@
+Significance: patch
+Type: performance
+
+Reduced the number of SQL queries needed to populate cart data in StoreApi.
diff --git a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
index 55c9a735151..0bf991771b1 100644
--- a/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
+++ b/plugins/woocommerce/includes/data-stores/class-wc-product-variable-data-store-cpt.php
@@ -128,6 +128,17 @@ class WC_Product_Variable_Data_Store_CPT extends WC_Product_Data_Store_CPT imple
* @since 3.0.0
*/
protected function read_product_data( &$product ) {
+ // Prime caches to reduce future queries.
+ $product_id = $product->get_id();
+ wp_prime_option_caches(
+ array(
+ '_transient_wc_var_prices_' . $product_id,
+ '_transient_timeout_wc_var_prices_' . $product_id,
+ '_transient_wc_product_children_' . $product_id,
+ '_transient_timeout_wc_product_children_' . $product_id,
+ )
+ );
+
parent::read_product_data( $product );
// Make sure data which does not apply to variables is unset.
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/Checkout.php b/plugins/woocommerce/src/Blocks/BlockTypes/Checkout.php
index 9208795331c..479a0969668 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/Checkout.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/Checkout.php
@@ -449,6 +449,21 @@ class Checkout extends AbstractBlock {
$this->asset_data_registry->add( 'addressAutocompleteProviders', $providers_payload );
$this->asset_data_registry->add( 'countryData', $country_data );
$this->asset_data_registry->add( 'defaultAddressFormat', $address_formats['default'] );
+
+ // Prime caches to reduce future queries.
+ wp_prime_option_caches(
+ array(
+ 'woocommerce_enable_guest_checkout',
+ 'woocommerce_enable_signup_and_login_from_checkout',
+ 'woocommerce_enable_checkout_login_reminder',
+ 'woocommerce_tax_display_cart', // This one is autoloaded, but we add it here for clarity.
+ 'woocommerce_tax_total_display',
+ 'woocommerce_ship_to_destination',
+ 'woocommerce_registration_generate_password',
+ 'pickup_location_pickup_locations',
+ )
+ );
+
$this->asset_data_registry->add(
'checkoutAllowsGuest',
false === filter_var(
@@ -463,16 +478,6 @@ class Checkout extends AbstractBlock {
FILTER_VALIDATE_BOOLEAN
)
);
- // Prime caches to reduce future queries.
- wp_prime_option_caches(
- array(
- 'woocommerce_enable_checkout_login_reminder',
- 'woocommerce_tax_display_cart', // This one is autoloaded, but we add it here for clarity.
- 'woocommerce_tax_total_display',
- 'woocommerce_ship_to_destination',
- 'woocommerce_registration_generate_password',
- )
- );
$this->asset_data_registry->add( 'checkoutShowLoginReminder', filter_var( get_option( 'woocommerce_enable_checkout_login_reminder' ), FILTER_VALIDATE_BOOLEAN ) );
$this->asset_data_registry->add( 'displayCartPricesIncludingTax', 'incl' === get_option( 'woocommerce_tax_display_cart' ) );
$this->asset_data_registry->add( 'displayItemizedTaxes', 'itemized' === get_option( 'woocommerce_tax_total_display' ) );
diff --git a/plugins/woocommerce/src/StoreApi/Schemas/V1/CartSchema.php b/plugins/woocommerce/src/StoreApi/Schemas/V1/CartSchema.php
index ead3e61f37c..0f0c0303738 100644
--- a/plugins/woocommerce/src/StoreApi/Schemas/V1/CartSchema.php
+++ b/plugins/woocommerce/src/StoreApi/Schemas/V1/CartSchema.php
@@ -347,17 +347,19 @@ class CartSchema extends AbstractSchema {
if ( ! empty( $cross_sell_ids ) ) {
// Prime caches to reduce future queries.
_prime_post_caches( $cross_sell_ids );
- $cross_sells = array_filter( array_map( 'wc_get_product', $cross_sell_ids ), 'wc_products_array_filter_visible' );
+ $cross_sells = array_values( array_filter( array_map( 'wc_get_product', $cross_sell_ids ), 'wc_products_array_filter_visible' ) );
/** @var \WC_Product[] $cross_sells */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort
// Identify which images need priming.
- $image_ids[] = array_values( array_filter( array_map( static fn( $product ) => (int) $product->get_image_id(), $cross_sells ) ) );
+ $ids = array_map( static fn( $product ) => array( (int) $product->get_image_id(), ...$product->get_gallery_image_ids() ), $cross_sells );
+ $image_ids[] = array_values( array_filter( array_merge( ...$ids ) ) );
}
$cart_all_items = $cart->get_cart();
- $cart_line_items = array_filter( $cart_all_items, static fn( $item ) => ( $item['data'] ?? null ) instanceof \WC_Product );
+ $cart_line_items = array_values( array_filter( $cart_all_items, static fn( $item ) => ( $item['data'] ?? null ) instanceof \WC_Product ) );
if ( ! empty( $cart_line_items ) ) {
// Identify which images need priming.
- $image_ids[] = array_values( array_filter( array_map( static fn( $item ) => (int) $item['data']->get_image_id(), $cart_line_items ) ) );
+ $ids = array_map( static fn( $item ) => array( (int) $item['data']->get_image_id(), ...$item['data']->get_gallery_image_ids() ), $cart_line_items );
+ $image_ids[] = array_values( array_filter( array_merge( ...array_values( $ids ) ) ) );
}
if ( ! empty( $image_ids ) ) {