静态网站暗色模式存储优化 替代Cookie/LocalStorage实现快速重载
你遇到的页面刷新先亮后暗的闪烁问题,和存储方式无关,是主题切换逻辑的执行时机太晚导致的。本地测试时资源加载速度快,延迟不明显;部署到线上后资源加载有耗时,JS执行滞后,就会出现明显的样式切换延迟。
先修正现有代码的隐藏bug
你目前的两个存储读取函数都存在死代码问题,默认值写入逻辑完全失效:
getCookie函数中,return语句后的document.cookie = "darkflag = 1"永远不会执行getLS函数中,else分支先执行了return,后面的localStorage.setItem同样永远不会执行
修正后的函数参考:
function getCookie(cname) { let name = cname + "="; let decodedCookie = decodeURIComponent(document.cookie); let ca = decodedCookie.split(';'); for (let i = 0; i < ca.length; i++) { let c = ca[i]; while (c.charAt(0) == ' ') { c = c.substring(1); } if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); } } // 不存在的话先设置默认值再返回 document.cookie = "darkflag=1; path=/; max-age=31536000"; return "1"; } function getLS(cname) { let val = localStorage.getItem(cname); if (val !== null && val !== ''){ return val; } else { // 先设置默认值再返回 localStorage.setItem("darkflag", "1"); return "1"; } }
最优解决方案:提前执行主题检测逻辑
把主题检测逻辑直接内联写在页面<head>标签的最前面,不需要等待DOM加载、资源加载完成,解析到这段代码时直接执行,在页面内容渲染前就完成主题样式设置,完全消除闪烁:
- 把主题变量从JS动态设置改为CSS类控制,减少JS运行开销:
/* 全局默认亮色主题变量 */ :root { --bg: #fff; --font: #333; --sidebarbg: #f5f5f5; /* 其余亮色模式变量 */ } /* 暗色主题类,覆盖变量 */ .dark { --bg: #040407; --font: #eee; --sidebarbg: #111; /* 其余暗色模式变量 */ }
- 在
<head>内加入内联JS,提前检测主题:
<script> // 直接读取存储,不需要等任何加载事件 const darkflag = localStorage.getItem('darkflag') ?? getCookie('darkflag') ?? '1'; if (darkflag === '0') { document.documentElement.classList.add('dark'); } </script>
- 调整主题切换逻辑:
function toggleDarkMode() { const isDark = document.documentElement.classList.toggle('dark'); const flag = isDark ? '0' : '1'; // 同步写入两种存储 localStorage.setItem('darkflag', flag); document.cookie = `darkflag=${flag}; path=/; max-age=31536000`; }
存储方式说明
LocalStorage和Cookie都完全可以满足暗色模式标记位的存储需求,不需要更换其他存储方案。如果需要服务端渲染时也能识别用户主题偏好,可以优先用Cookie存储,Cookie会随请求自动发送给服务端;如果仅前端控制主题,LocalStorage更轻便,容量更大。
内容的提问来源于stack exchange,提问作者Amlan Saha Kundu
相关产品推荐
相关产品推荐

