I have been looking around at ways to have a mobile efficient dark mode theme, that is both automatic and can be toggled. By mobile efficient I mean high-latency, low-bandwidth, low-CPU friendly:
- only the relevant stylesheet is loaded (when light is active, dark stylesheet is not loaded, and vice-versa) to save on bandwidth
- no full-screen flashing
- no cookies
Solutions I have found do not have these properties, they are either using a fat CSS with both themes combined, or they're using two stylesheets, which can results in full-screen flashes when the user chose a theme different from the system default (as they are controlled through JS executed after the stylesheets are referenced in the DOM).
My best alternative so far is "efficient", but relies on document.write in a small inline script in the document head, it goes like:
let theme = localStorage.getItem("theme");
if (!theme) {
theme = (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches)?"dark":"light"
}
if (theme == "dark") {
document.write('<link rel="stylesheet" href="dark.theme.css" />');
} else {
document.write('<link rel="stylesheet" href="light.theme.css" />');
}
The localStorage entry is managed by regular JS when manually toggled by the user.
I have tried all ways to mutate the link DOM element, and they all fail, resulting either in flashing or delayed CSS loading (with non-presented HTML being transiently visible).
I wonder if there is an approach that would still be efficient, support toggle and not rely on document.write ?