diff --git a/core/lib/Drupal/Core/Asset/AssetResolver.php b/core/lib/Drupal/Core/Asset/AssetResolver.php
index 3355801a4d320394650e640f99091ab04e1bbe00..2d3f8ebee66db68a4f69d2af97df29561e8747c8 100644
--- a/core/lib/Drupal/Core/Asset/AssetResolver.php
+++ b/core/lib/Drupal/Core/Asset/AssetResolver.php
@@ -125,13 +125,24 @@ public function getCssAssets(AttachedAssetsInterface $assets, $optimize, Languag
     if (!$assets->getLibraries()) {
       return [];
     }
+    $libraries_to_load = $this->getLibrariesToLoad($assets);
+    foreach ($libraries_to_load as $key => $library) {
+      [$extension, $name] = explode('/', $library, 2);
+      $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
+      if (empty($definition['css'])) {
+        unset($libraries_to_load[$key]);
+      }
+    }
+    $libraries_to_load = array_values($libraries_to_load);
+    if (!$libraries_to_load) {
+      return [];
+    }
     if (!isset($language)) {
       $language = $this->languageManager->getCurrentLanguage();
     }
     $theme_info = $this->themeManager->getActiveTheme();
     // Add the theme name to the cache key since themes may implement
     // hook_library_info_alter().
-    $libraries_to_load = $this->getLibrariesToLoad($assets);
     $cid = 'css:' . $theme_info->getName() . ':' . $language->getId() . Crypt::hashBase64(serialize($libraries_to_load)) . (int) $optimize;
     if ($cached = $this->cache->get($cid)) {
       return $cached->data;
@@ -149,11 +160,6 @@ public function getCssAssets(AttachedAssetsInterface $assets, $optimize, Languag
     foreach ($libraries_to_load as $key => $library) {
       [$extension, $name] = explode('/', $library, 2);
       $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
-      if (empty($definition['css'])) {
-        unset($libraries_to_load[$key]);
-        continue;
-      }
-
       foreach ($definition['css'] as $options) {
         $options += $default_options;
         // Copy the asset library license information to each file.
@@ -227,10 +233,34 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize, Language
       $language = $this->languageManager->getCurrentLanguage();
     }
     $theme_info = $this->themeManager->getActiveTheme();
+    $libraries_to_load = $this->getLibrariesToLoad($assets);
+
+    // 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 $key => $library) {
+      [$extension, $name] = explode('/', $library, 2);
+      $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
+      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);
+
+    // If all the libraries to load contained only CSS, there is nothing further
+    // to do here, so return early.
+    if (!$libraries_to_load && !$assets->getSettings()) {
+      return [[], []];
+    }
+
     // Add the theme name to the cache key since themes may implement
     // hook_library_info_alter(). Additionally add the current language to
     // support translation of JavaScript files via hook_js_alter().
-    $libraries_to_load = $this->getLibrariesToLoad($assets);
     $cid = 'js:' . $theme_info->getName() . ':' . $language->getId() . ':' . Crypt::hashBase64(serialize($libraries_to_load)) . (int) (count($assets->getSettings()) > 0) . (int) $optimize;
 
     if ($cached = $this->cache->get($cid)) {
@@ -248,22 +278,6 @@ public function getJsAssets(AttachedAssetsInterface $assets, $optimize, Language
         'version' => NULL,
       ];
 
-      // 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 $key => $library) {
-        [$extension, $name] = explode('/', $library, 2);
-        $definition = $this->libraryDiscovery->getLibraryByName($extension, $name);
-        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.
diff --git a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
index 35977e4bcd423094cda6b1e60c7c62520fe4f53f..19f0724d7fc7157376cd4f2b2fe77caf5d27e104 100644
--- a/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
+++ b/core/profiles/standard/tests/src/FunctionalJavascript/StandardPerformanceTest.php
@@ -111,10 +111,10 @@ public function testAnonymous() {
     $this->assertSame($expected_queries, $recorded_queries);
     $this->assertSame(34, $performance_data->getQueryCount());
     $this->assertSame(124, $performance_data->getCacheGetCount());
-    $this->assertSame(46, $performance_data->getCacheSetCount());
+    $this->assertSame(45, $performance_data->getCacheSetCount());
     $this->assertSame(0, $performance_data->getCacheDeleteCount());
-    $this->assertSame(37, $performance_data->getCacheTagChecksumCount());
-    $this->assertSame(42, $performance_data->getCacheTagIsValidCount());
+    $this->assertSame(36, $performance_data->getCacheTagChecksumCount());
+    $this->assertSame(43, $performance_data->getCacheTagIsValidCount());
     $this->assertSame(0, $performance_data->getCacheTagInvalidationCount());
 
     // Test node page.
diff --git a/core/tests/Drupal/Tests/Core/Asset/AssetResolverTest.php b/core/tests/Drupal/Tests/Core/Asset/AssetResolverTest.php
index c36b39fa8cf5a3aba36fa72ed322840afb84899a..9a23e5d7cac7a357895462cff780df429fdcfa3c 100644
--- a/core/tests/Drupal/Tests/Core/Asset/AssetResolverTest.php
+++ b/core/tests/Drupal/Tests/Core/Asset/AssetResolverTest.php
@@ -76,6 +76,10 @@ class AssetResolverTest extends UnitTestCase {
    * A mocked Japanese language object.
    */
   protected LanguageInterface $japanese;
+  /**
+   * An array of library definitions.
+   */
+  protected $libraries = [];
 
   /**
    * {@inheritdoc}
@@ -86,6 +90,44 @@ protected function setUp(): void {
     $this->libraryDiscovery = $this->getMockBuilder('Drupal\Core\Asset\LibraryDiscovery')
       ->disableOriginalConstructor()
       ->getMock();
+    $this->libraries = [
+      'drupal' => [
+        'version' => '1.0.0',
+        'css' => [],
+        'js' =>
+        [
+          'core/misc/drupal.js' => ['data' => 'core/misc/drupal.js', 'preprocess' => TRUE],
+        ],
+        'license' => '',
+      ],
+      'jquery' => [
+        'version' => '1.0.0',
+        'css' => [],
+        'js' =>
+        [
+          'core/misc/jquery.js' => ['data' => 'core/misc/jquery.js', 'minified' => TRUE],
+        ],
+        'license' => '',
+      ],
+      'llama' => [
+        'version' => '1.0.0',
+        'css' =>
+        [
+          'core/misc/llama.css' => ['data' => 'core/misc/llama.css'],
+        ],
+        'js' => [],
+        'license' => '',
+      ],
+      'piggy' => [
+        'version' => '1.0.0',
+        'css' =>
+        [
+          'core/misc/piggy.css' => ['data' => 'core/misc/piggy.css'],
+        ],
+        'js' => [],
+        'license' => '',
+      ],
+    ];
     $this->libraryDependencyResolver = $this->createMock('\Drupal\Core\Asset\LibraryDependencyResolverInterface');
     $this->libraryDependencyResolver->expects($this->any())
       ->method('getLibrariesWithDependencies')
@@ -124,40 +166,77 @@ protected function setUp(): void {
 
   /**
    * @covers ::getCssAssets
-   * @dataProvider providerAttachedAssets
+   * @dataProvider providerAttachedCssAssets
    */
-  public function testGetCssAssets(AttachedAssetsInterface $assets_a, AttachedAssetsInterface $assets_b, $expected_cache_item_count) {
+  public function testGetCssAssets(AttachedAssetsInterface $assets_a, AttachedAssetsInterface $assets_b, $expected_css_cache_item_count) {
+    $this->libraryDiscovery->expects($this->any())
+      ->method('getLibraryByName')
+      ->willReturnOnConsecutiveCalls(
+        $this->libraries['drupal'],
+        $this->libraries['llama'],
+        $this->libraries['llama'],
+        $this->libraries['piggy'],
+        $this->libraries['piggy'],
+      );
     $this->assetResolver->getCssAssets($assets_a, FALSE, $this->english);
     $this->assetResolver->getCssAssets($assets_b, FALSE, $this->english);
-    $this->assertCount($expected_cache_item_count, $this->cache->getAllCids());
+    $this->assertCount($expected_css_cache_item_count, $this->cache->getAllCids());
+  }
+
+  public static function providerAttachedCssAssets() {
+    $time = time();
+    return [
+      'one js only library and one css only library' => [
+        (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal']),
+        (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['llama/css']),
+        1,
+      ],
+      'two different css libraries' => [
+        (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal', 'llama/css']),
+        (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['piggy/css']),
+        2,
+      ],
+    ];
   }
 
   /**
    * @covers ::getJsAssets
-   * @dataProvider providerAttachedAssets
+   * @dataProvider providerAttachedJsAssets
    */
-  public function testGetJsAssets(AttachedAssetsInterface $assets_a, AttachedAssetsInterface $assets_b, $expected_cache_item_count) {
+  public function testGetJsAssets(AttachedAssetsInterface $assets_a, AttachedAssetsInterface $assets_b, $expected_js_cache_item_count, $expected_multilingual_js_cache_item_count) {
+    $this->libraryDiscovery->expects($this->any())
+      ->method('getLibraryByName')
+      ->willReturnOnConsecutiveCalls(
+        $this->libraries['drupal'],
+        $this->libraries['drupal'],
+        $this->libraries['jquery'],
+        $this->libraries['drupal'],
+        $this->libraries['drupal'],
+        $this->libraries['jquery'],
+      );
     $this->assetResolver->getJsAssets($assets_a, FALSE, $this->english);
     $this->assetResolver->getJsAssets($assets_b, FALSE, $this->english);
-    $this->assertCount($expected_cache_item_count, $this->cache->getAllCids());
+    $this->assertCount($expected_js_cache_item_count, $this->cache->getAllCids());
 
     $this->assetResolver->getJsAssets($assets_a, FALSE, $this->japanese);
     $this->assetResolver->getJsAssets($assets_b, FALSE, $this->japanese);
-    $this->assertCount($expected_cache_item_count * 2, $this->cache->getAllCids());
+    $this->assertCount($expected_multilingual_js_cache_item_count, $this->cache->getAllCids());
   }
 
-  public static function providerAttachedAssets() {
+  public static function providerAttachedJsAssets() {
     $time = time();
     return [
       'same libraries, different timestamps' => [
         (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal'])->setSettings(['currentTime' => $time]),
         (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal'])->setSettings(['currentTime' => $time + 100]),
         1,
+        2,
       ],
       'different libraries, same timestamps' => [
         (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal'])->setSettings(['currentTime' => $time]),
         (new AttachedAssets())->setAlreadyLoadedLibraries([])->setLibraries(['core/drupal', 'core/jquery'])->setSettings(['currentTime' => $time]),
         2,
+        3,
       ],
     ];
   }