From 57f6dd86e23bc1feaa6474f83e72676476b62b3b Mon Sep 17 00:00:00 2001 From: abid Date: Mon, 6 Jul 2026 11:21:50 +0600 Subject: [PATCH] Fix N+1 queries: cache inline notifications data per request Growth Alert (inline) hooks fire once per product on WooCommerce shop/archive pages, and each run re-queried the database for data that only varies by source. Restore request-level memoization in Inline::get_notifications_data(), keyed by source so different inline sources cannot receive each other's cached data. Measured on an 11-product archive with one active Growth Alert: Database->get_posts calls drop from 137 to 11 per page load with identical rendered output. Co-Authored-By: Claude Fable 5 --- includes/Features/Inline.php | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/includes/Features/Inline.php b/includes/Features/Inline.php index fa9a36ed0..48327d844 100644 --- a/includes/Features/Inline.php +++ b/includes/Features/Inline.php @@ -23,6 +23,15 @@ class Inline { public $notifications_data = []; + /** + * Request-level cache of notifications data, keyed by source. + * Inline hooks fire once per product in shop/archive loops; the + * result only varies by $source, so compute it once per request. + * + * @var array + */ + protected $notifications_cache = []; + /** * __construct__ is for revoke first time to get ready * @@ -35,33 +44,37 @@ public function __construct() { public function get_notifications_data( $source, $id = null, $settings = [] ) { - + $exit = apply_filters('nx_inline_notifications_data', null, $source, $id, $settings); if($exit){ return $exit; } - // if ( empty( $this->notifications_data ) ) { - $this->notifications_data = array( 'shortcode' => array() ); - $notifications = PostType::get_instance()->get_posts( + if ( ! isset( $this->notifications_cache[ $source ] ) ) { + $data = array( 'shortcode' => array() ); + $notifications = PostType::get_instance()->get_posts( array( 'source' => $source, 'enabled' => true, 'is_inline' => true, ) ); - + do_action( 'nx_inline' ); if ( ! empty( $notifications ) ) { - $this->notifications_data = FrontEnd::get_instance()->get_notifications_data( + $data = FrontEnd::get_instance()->get_notifications_data( array( 'shortcode' => array_column( $notifications, 'nx_id' ), 'inline_shortcode' => true, ) ); } - // } + + $this->notifications_cache[ $source ] = $data; + } + + $this->notifications_data = $this->notifications_cache[ $source ]; return $this->notifications_data; }