FOUC是浏览器先渲染无样式HTML再重绘导致的闪白或布局跳动;内联关键CSS可让首屏样式在首次绘制前就绪,提前实现有样式的首帧渲染。

FOUC是什么,为什么内联CSS能缓解
FOUC(Flash of Unstyled Content)是浏览器先渲染无样式HTML、再等CSS加载完才重绘导致的“闪白”或布局跳动。它不是bug,而是浏览器默认渲染流程:HTML解析→构建DOM→遇到就暂停渲染,但部分浏览器(尤其旧版Safari、IE)会先显示未样式化内容,等CSS就绪再回填——这就是FOUC。
内联关键CSS(Critical CSS)把首屏必需的样式直接写进<style></style>标签里,绕过HTTP请求阻塞,让浏览器在首次绘制前就拿到样式规则。这不是消灭FOUC,而是把“有样式的首次渲染”提前到第一帧。
怎么提取和内联关键CSS
关键CSS ≠ 全部CSS,而是首屏可见区域(above-the-fold)用到的选择器及其声明。手动提取极易遗漏或冗余,推荐工具链辅助:
- 用
Puppeteer或playwright模拟首屏渲染,抓取实际用到的样式规则 -
critical(Node.js库)可自动注入HTML:critical.generate({ base: 'dist/', src: 'index.html', inline: true, minify: true }) - 构建时集成:Webpack用
critters-webpack-plugin,Vite用vite-plugin-critical
注意:内联内容体积建议控制在14KB以内(避免触发TCP慢启动额外往返),超出后仍需异步加载剩余CSS。
立即学习“前端免费学习笔记(深入)”;
内联后还要注意哪些兼容性陷阱
内联CSS本身无兼容问题,但组合使用时容易踩坑:
-
@import不能出现在<style></style>块内——会被忽略,必须转为@media或拆成独立<link> - 内联样式中若含
url()相对路径(如background: url(./img/icon.png)),路径会相对于当前HTML文档,而非原CSS文件位置,易404 - 服务端渲染(SSR)场景下,若HTML已内联CSS,但客户端JS又动态
document.createElement('link')加载同一份CSS,可能触发重复解析甚至样式抖动 - HTTP/2 Push已废弃,别再依赖它“预推”CSS;现代方案只靠内联+
preload配合
要不要加preload?怎么加才不翻车
要加,但仅用于非关键CSS。关键CSS已内联,无需再preload;而剩余CSS应明确标记为异步加载:
<link rel="preload" href="/css/async.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> <noscript><link rel="stylesheet" href="/css/async.css"></noscript>
重点看onload赋值逻辑:防止多次执行;noscript兜底保障无JS时仍可加载。别用rel="prefetch"替代——它不保证优先级,对首屏无意义。
真正难的是界定“关键”边界:字体加载、动画触发时机、响应式断点切换都可能让首屏样式依赖延迟到达的资源。这类情况光靠内联不够,得配合font-display: optional、contain: layout style等协同压制FOUC感知。


















