From b3238209ea28c6dc555e1b620c74bc233fa11f6a Mon Sep 17 00:00:00 2001 From: Dave Long <dave@longwaveconsulting.com> Date: Tue, 6 May 2025 23:05:12 +0100 Subject: [PATCH] Issue #3513928 by catch, kristiaanvandeneynde: Recursively replace placeholders in CachedStrategy --- .../Render/Placeholder/CachedStrategy.php | 36 ++++++++++++++++++- .../FunctionalJavascript/PerformanceTest.php | 4 +-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php b/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php index 941c11ac27eb..757f647e5f0a 100644 --- a/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php +++ b/core/lib/Drupal/Core/Render/Placeholder/CachedStrategy.php @@ -21,7 +21,41 @@ public function __construct( * {@inheritdoc} */ public function processPlaceholders(array $placeholders) { - return $this->renderCache->getMultiple($placeholders); + $return = $this->renderCache->getMultiple($placeholders); + if ($return) { + $return = $this->processNestedPlaceholders($return); + } + + return $return; + } + + /** + * Fetch any nested placeholders from cache. + * + * Placeholders returned from cache may have placeholders in #attached, which + * can themselves be fetched from the cache. By recursively processing the + * placeholders here, we're able to use multiple cache get to fetch the cache + * items at each level of recursion. + */ + private function processNestedPlaceholders(array $placeholders): array { + $sets = []; + foreach ($placeholders as $key => $placeholder) { + if (!empty($placeholder['#attached']['placeholders'])) { + $sets[] = $placeholder['#attached']['placeholders']; + } + } + if ($sets) { + $cached = $this->renderCache->getMultiple(...array_merge($sets)); + if ($cached) { + $cached = $this->processNestedPlaceholders($cached); + foreach ($placeholders as $key => $placeholder) { + if (!empty($placeholder['#attached']['placeholders'])) { + $placeholders[$key]['#attached']['placeholders'] = array_replace($placeholder['#attached']['placeholders'], $cached); + } + } + } + } + return $placeholders; } } diff --git a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php index 3264d769c195..f1ca3242a2a8 100644 --- a/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php +++ b/core/modules/navigation/tests/src/FunctionalJavascript/PerformanceTest.php @@ -73,14 +73,14 @@ public function testLogin(): void { $expected = [ 'QueryCount' => 4, - 'CacheGetCount' => 49, + 'CacheGetCount' => 48, 'CacheGetCountByBin' => [ 'config' => 11, 'data' => 4, 'discovery' => 10, 'bootstrap' => 6, 'dynamic_page_cache' => 1, - 'render' => 16, + 'render' => 15, 'menu' => 1, ], 'CacheSetCount' => 2, -- GitLab