diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 5733d1f9c79d6..72ef9b3e347d3 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -651,7 +651,22 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
                      <script defer src=\"{root_path}settings{suffix}.js\"></script>",
                     root_path = page.static_root_path.unwrap_or(""),
                     suffix = page.resource_suffix,
-                )
+                );
+                // Pre-load all theme CSS files, so that switching feels seamless.
+                //
+                // When loading settings.html as a popover, the equivalent HTML is
+                // generated in main.js.
+                for file in &shared.style_files {
+                    if let Ok(theme) = file.basename() {
+                        write!(
+                            buf,
+                            "<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \
+                                as=\"style\">",
+                            root_path = page.static_root_path.unwrap_or(""),
+                            suffix = page.resource_suffix,
+                        );
+                    }
+                }
             },
             &shared.style_files,
         );
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 33480fa41cf07..28460514b4630 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -191,6 +191,15 @@ function loadCss(cssFileName) {
     document.getElementsByTagName("head")[0].appendChild(link);
 }
 
+function preLoadCss(cssFileName) {
+    // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
+    const link = document.createElement("link");
+    link.href = resourcePath(cssFileName, ".css");
+    link.rel = "preload";
+    link.as = "style";
+    document.getElementsByTagName("head")[0].appendChild(link);
+}
+
 (function() {
     const isHelpPage = window.location.pathname.endsWith("/help.html");
 
@@ -210,6 +219,16 @@ function loadCss(cssFileName) {
         // hopefully be loaded when the JS will generate the settings content.
         loadCss("settings");
         loadScript(resourcePath("settings", ".js"));
+        // Pre-load all theme CSS files, so that switching feels seamless.
+        //
+        // When loading settings.html as a standalone page, the equivalent HTML is
+        // generated in context.rs.
+        setTimeout(() => {
+            const themes = getVar("themes").split(",");
+            for (const theme of themes) {
+                preLoadCss(theme);
+            }
+        }, 0);
     };
 
     window.searchState = {
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index b462a2c50f145..a8ada3b6bfc40 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -44,8 +44,6 @@ function getSettingValue(settingName) {
 
 const localStoredTheme = getSettingValue("theme");
 
-const savedHref = [];
-
 // eslint-disable-next-line no-unused-vars
 function hasClass(elem, className) {
     return elem && elem.classList && elem.classList.contains(className);
@@ -103,6 +101,7 @@ function onEach(arr, func, reversed) {
  * @param {function(?)}                   func       - The callback
  * @param {boolean}                       [reversed] - Whether to iterate in reverse
  */
+// eslint-disable-next-line no-unused-vars
 function onEachLazy(lazyArray, func, reversed) {
     return onEach(
         Array.prototype.slice.call(lazyArray),
@@ -140,21 +139,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
         return;
     }
 
-    let found = false;
-    if (savedHref.length === 0) {
-        onEachLazy(document.getElementsByTagName("link"), el => {
-            savedHref.push(el.href);
-        });
-    }
-    onEach(savedHref, el => {
-        if (el === newHref) {
-            found = true;
-            return true;
-        }
-    });
-    if (found) {
-        styleElem.href = newHref;
-    }
+    styleElem.href = newHref;
 }
 
 // This function is called from "main.js".
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index c323869168789..6666fa8b377dd 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -18,16 +18,9 @@
     <link rel="stylesheet" {# -#}
           href="{{static_root_path|safe}}rustdoc{{page.resource_suffix}}.css" {# -#}
           id="mainThemeStyle"> {#- -#}
-    {%- for theme in themes -%}
-        <link rel="stylesheet" {# -#}
-            href="{{static_root_path|safe}}{{theme}}{{page.resource_suffix}}.css" {# -#}
-        {%- if theme == "light" -%}
-            id="themeStyle"
-        {%- else -%}
-            disabled
-        {%- endif -%}
-        >
-    {%- endfor -%}
+    <link rel="stylesheet" {# -#}
+        href="{{static_root_path|safe}}light{{page.resource_suffix}}.css" {# -#}
+        id="themeStyle"> {#- -#}
     <script id="default-settings" {# -#}
       {% for (k, v) in layout.default_settings %}
         data-{{k}}="{{v}}"