Dark mode flickers a white background for a millisecond on reload

It would be ideal to block the page rendering by placing a small <script> tag inside the <head> of your Document. By doing so the renderer should stop to call the JavaScript interpreter, assign the data-theme attribute to <html> and than continue where left. Give it a try:

Place this <script> inside <head> – even before the <link> or <style> tags:

<head>
  <!-- meta, title etc... -->

  <script>
  // Render blocking JS:
  if (localStorage.theme) document.documentElement.setAttribute("data-theme", localStorage.theme);
  </script>

  <!-- link, style, etc... -->
</head>

Than, right before the closing </body> tag use all the other scripts in a non-render-blocking manner:


<!-- other <script> tags here -->

<script>
const toggleSwitch = document.querySelector('#dark-mode-button input[type="checkbox"]');

if (localStorage.theme) {
  toggleSwitch.checked = localStorage.theme === "dark";
}

function switchTheme(e) {
  const theme = e.target.checked ? "dark" : "light";
  document.documentElement.setAttribute("data-theme", theme);
  localStorage.theme = theme;
}

toggleSwitch.addEventListener("change", switchTheme);
</script>

    
<!-- Closing </body> goes here -->

Leave a Comment