FOUC本质是浏览器先渲染无样式DOM再应用CSS导致的闪屏,根本原因是HTML解析与CSS加载/解析时序竞争;关键在确保关键样式阻塞渲染,仅放不够,需内联关键CSS、合理使用preload+onload、避免media不匹配或@import等破坏阻塞链的行为。

因为浏览器解析 HTML 是自上而下进行的,link 标签在 中才能触发“渲染阻塞”行为——即暂停绘制,直到 CSSOM 构建完成。放错位置(比如 里)或加载方式不当,就会导致 FOUC(Flash of Unstyled Content)。
为什么 CSS 放在 里仍会闪
放对位置只是基础条件,不是充分条件。常见原因包括:
-
@import在 CSS 文件中串行加载,延迟关键样式就绪时间 - 外部
link没配rel="preload"+onload注入逻辑,下载完成却不自动应用 - 用了
media属性但值不匹配(如media="(min-width: 768px)"),浏览器直接跳过加载 - JS 动态创建
link并插入document.head,绕过了 HTML 解析器预加载机制
rel="preload" 必须配 as="style" 和 onload
仅写 <link rel="preload" href="main.css"> 是无效的:浏览器不会识别为样式资源,也不会在加载后自动应用。
-
as="style"告诉浏览器这是样式资源,参与优先级调度和缓存策略 -
onload回调必须显式设置this.rel = 'stylesheet',否则资源下载完仍不生效 - IE 不支持
preload,需降级写法:<link rel="stylesheet" href="critical.css">紧跟在preload后面
内联关键 CSS 是唯一 100% 可控的方案
网络不可控,但 HTML 是同步交付的。把首屏必需的样式(如 .header、.hero、字体重置)提取出来,用 <style></style> 写进 ,就能绕过所有请求延迟。
- 体积建议 ≤ 14KB,避免阻塞 HTML 解析太久
- 内联后要移除对应外链,否则样式重复可能引发优先级冲突
- 工具推荐:
critters(Webpack)、vite-plugin-critical-css(Vite)、next-critical-css(Next.js)
真正容易被忽略的是:CSS 加载是否“阻塞渲染”,不取决于它在不在 ,而取决于浏览器是否在首次绘制前确认了关键样式已就绪。这需要内联 + preload + media 隔离三者配合,缺一不可。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











