直接换link.href一定会闪屏,因浏览器需卸载旧样式再加载新CSS,产生无样式空白期;应预加载所有皮肤CSS并用disabled控制启用状态,避免网络请求与解析延迟。

直接换 link.href 一定会闪屏,这不是网络慢的问题
浏览器遇到 link.href 变更,会立即卸载旧样式表,再发起新请求——中间存在「无样式窗口期」。哪怕 CSS 文件只有几 KB,这个 gap 也足够让 body 用默认白色背景渲染一帧,尤其在移动端弱网或首屏 DOM 较大时更明显。这不是 JS 执行慢,是浏览器渲染机制决定的:样式表切换必须经历“卸载→下载→解析→应用”全过程。
正确做法:所有主题 CSS 预加载 + 用 disabled 切换启用状态
核心是绕过卸载和重新下载,让所有皮肤 CSS 始终在 DOM 中,只控制是否生效:
- HTML 中提前写好全部主题
link标签,初始设disabled:<link id="theme-light" rel="stylesheet" href="/css/theme-light.css" disabled><br><link id="theme-dark" rel="stylesheet" href="/css/theme-dark.css" disabled>
- JS 切换时只改
disabled状态:document.getElementById('theme-light').disabled = true;<br>document.getElementById('theme-dark').disabled = false; - 确保所有主题 CSS 文件体积 ≤150KB,避免预加载拖慢首屏;若超限,需拆分关键/非关键规则
为什么 media="print" + onload 不适合主题切换
这种技巧常被误用于“异步加载非关键 CSS”,但它对主题切换反而有害:
-
media="print"会让样式表延迟到 onload 触发后才应用,用户点击切换按钮后要等整个 CSS 文件下载完才能看到效果,体验卡顿 - IE 不支持
onload,fallback 到onreadystatechange易出竞态,且无法保证样式应用时机 - 它本质仍是“加载后启用”,没解决多主题间快速切换的需求;而
disabled是即时生效的 DOM 属性,无需等待资源到达
容易被忽略的细节:首帧背景色必须内联,且不能依赖 JS 注入
即使用了 disabled 切换,如果 HTML 的 里没内联 body { background-color: #f8f9fa } 这类最简背景色,移动端刷新时仍会在第一帧渲染出纯白顶部——因为浏览器在 CSSOM 构建完成前就用默认值绘制了 body。
更关键的是:别把主题 class(如 html[data-theme="dark"])留到 JS 加载后再加。必须由服务端或构建时直接写死在 HTML 模板中,例如:
否则 JS 加载前页面先按 light 渲染,JS 执行后又切 dark,造成二次跳变,比白屏还刺眼。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











