diff --git a/core/lib/Drupal/Core/Asset/AssetResolver.php b/core/lib/Drupal/Core/Asset/AssetResolver.php index 251b9036f3a5de4bb265531c5b461f5d9b28fbbf..2a2ce62e1a0e2e5a836b9ea6e27fd034bf2b2eb3 100644 --- a/core/lib/Drupal/Core/Asset/AssetResolver.php +++ b/core/lib/Drupal/Core/Asset/AssetResolver.php @@ -143,27 +143,30 @@ public function getCssAssets(AttachedAssetsInterface $assets, $optimize, Languag 'preprocess' => TRUE, ]; - foreach ($libraries_to_load as $library) { + foreach ($libraries_to_load as $key => $library) { [$extension, $name] = explode('/', $library, 2); $definition = $this->libraryDiscovery->getLibraryByName($extension, $name); - if (isset($definition['css'])) { - foreach ($definition['css'] as $options) { - $options += $default_options; - // Copy the asset library license information to each file. - $options['license'] = $definition['license']; - - // Files with a query string cannot be preprocessed. - if ($options['type'] === 'file' && $options['preprocess'] && str_contains($options['data'], '?')) { - $options['preprocess'] = FALSE; - } + if (empty($definition['css'])) { + unset($libraries_to_load[$key]); + continue; + } - // Always add a tiny value to the weight, to conserve the insertion - // order. - $options['weight'] += count($css) / 30000; + foreach ($definition['css'] as $options) { + $options += $default_options; + // Copy the asset library license information to each file. + $options['license'] = $definition['license']; - // CSS files are being keyed by the full path. - $css[$options['data']] = $options; + // Files with a query string cannot be preprocessed. + if ($options['type'] === 'file' && $options['preprocess'] && str_contains($options['data'], '?')) { + $options['preprocess'] = FALSE; } + + // Always add a tiny value to the weight, to conserve the insertion + // order. + $options['weight'] += count($css) / 30000; + + // CSS files are being keyed by the full path. + $css[$options['data']] = $options; } } @@ -176,7 +179,7 @@ public function getCssAssets(AttachedAssetsInterface $assets, $optimize, Languag uasort($css, [static::class, 'sort']); if ($optimize) { - $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css, $libraries_to_load, $language); + $css = \Drupal::service('asset.css.collection_optimizer')->optimize($css, array_values($libraries_to_load), $language); } } $this->cache->set($cid, $css, CacheBackendInterface::CACHE_PERMANENT, ['library_info']); @@ -240,14 +243,21 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize, Language ]; // Collect all libraries that contain JS assets and are in the header. + // Also remove any libraries with no JavaScript from the libraries to + // load. $header_js_libraries = []; - foreach ($libraries_to_load as $library) { + foreach ($libraries_to_load as $key => $library) { [$extension, $name] = explode('/', $library, 2); $definition = $this->libraryDiscovery->getLibraryByName($extension, $name); - if (isset($definition['js']) && !empty($definition['header'])) { + if (empty($definition['js'])) { + unset($libraries_to_load[$key]); + continue; + } + if (!empty($definition['header'])) { $header_js_libraries[] = $library; } } + $libraries_to_load = array_values($libraries_to_load); // The current list of header JS libraries are only those libraries that // are in the header, but their dependencies must also be loaded for them // to function correctly, so update the list with those. @@ -256,28 +266,26 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize, Language foreach ($libraries_to_load as $library) { [$extension, $name] = explode('/', $library, 2); $definition = $this->libraryDiscovery->getLibraryByName($extension, $name); - if (isset($definition['js'])) { - foreach ($definition['js'] as $options) { - $options += $default_options; - // Copy the asset library license information to each file. - $options['license'] = $definition['license']; - - // 'scope' is a calculated option, based on which libraries are - // marked to be loaded from the header (see above). - $options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer'; - - // Preprocess can only be set if caching is enabled and no - // attributes are set. - $options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE; - - // Always add a tiny value to the weight, to conserve the insertion - // order. - $options['weight'] += count($javascript) / 30000; - - // Local and external files must keep their name as the associative - // key so the same JavaScript file is not added twice. - $javascript[$options['data']] = $options; - } + foreach ($definition['js'] as $options) { + $options += $default_options; + // Copy the asset library license information to each file. + $options['license'] = $definition['license']; + + // 'scope' is a calculated option, based on which libraries are + // marked to be loaded from the header (see above). + $options['scope'] = in_array($library, $header_js_libraries) ? 'header' : 'footer'; + + // Preprocess can only be set if caching is enabled and no + // attributes are set. + $options['preprocess'] = $options['cache'] && empty($options['attributes']) ? $options['preprocess'] : FALSE; + + // Always add a tiny value to the weight, to conserve the insertion + // order. + $options['weight'] += count($javascript) / 30000; + + // Local and external files must keep their name as the associative + // key so the same JavaScript file is not added twice. + $javascript[$options['data']] = $options; } } diff --git a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php index 61b1b66543c25774f906ed20a77aca8597024883..49117a946d49f19c394e5ca802550f26c4cd2b93 100644 --- a/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php +++ b/core/profiles/demo_umami/tests/src/FunctionalJavascript/AssetAggregationAcrossPagesTest.php @@ -26,8 +26,8 @@ public function testFrontAndRecipesPages() { $performance_data = $this->doRequests(); $this->assertSame(4, $performance_data->getStylesheetCount()); $this->assertLessThan(82500, $performance_data->getStylesheetBytes()); - $this->assertSame(2, $performance_data->getScriptCount()); - $this->assertLessThan(14500, $performance_data->getScriptBytes()); + $this->assertSame(1, $performance_data->getScriptCount()); + $this->assertLessThan(7500, $performance_data->getScriptBytes()); } /** @@ -40,8 +40,8 @@ public function testFrontAndRecipesPagesAuthenticated() { $performance_data = $this->doRequests(); $this->assertSame(4, $performance_data->getStylesheetCount()); $this->assertLessThan(89500, $performance_data->getStylesheetBytes()); - $this->assertSame(2, $performance_data->getScriptCount()); - $this->assertLessThan(250000, $performance_data->getScriptBytes()); + $this->assertSame(1, $performance_data->getScriptCount()); + $this->assertLessThan(125500, $performance_data->getScriptBytes()); } /**