关键CSS是将首屏渲染必需的样式内联到HTML的中,使浏览器无需等待外部CSS即可绘制可用界面,从而避免白屏或样式错乱;它仅提取above-the-fold部分的选择器,如.header、.hero-banner等,排除滚动后内容。

什么是关键CSS,为什么它能解决闪屏
页面首次加载时出现白屏或样式错乱,本质是浏览器先渲染了无样式的HTML,等CSS文件下载解析完才重绘。关键CSS就是把首屏渲染必需的样式内联到里,让浏览器不用等外部style.css就能画出可用界面。
它不是把整个CSS塞进去,而是提取首屏(above-the-fold)用到的选择器:比如.header、.hero-banner、h1这些,不包括滚动后才出现的.footer或.modal。
常见错误现象:
- 首页加载瞬间文字放大、布局塌陷,1秒后突然“跳”成设计稿样式
- 使用
link rel="stylesheet"加载主CSS,且没做任何内联或预加载
怎么提取关键CSS:手动 vs 工具化流程
手动提取容易漏、难维护,尤其有伪类、媒体查询、动态类名时;工具化更可靠,但要注意输出范围和构建时机。
推荐方式(以现代前端项目为例):
- 用
critters(Vite/webpack插件):在构建时自动分析HTML + CSS,生成内联关键CSS,并异步加载剩余样式 - 用
penthouse(Node CLI):适合静态站点,需指定viewport尺寸和URL路径,例如penthouse --url https://example.com --css ./dist/style.css --width 1300 --height 900 - 避免直接复制
devtools → Coverage → 筛选CSS → 手动拷贝:覆盖率数据只反映当前交互路径,不等于首屏真实依赖
注意:critters默认不处理@import引入的CSS,若主文件含@import,需提前合并或改用postcss-import。
内联关键CSS后,怎么加载剩余样式
关键CSS只是“够用”,完整样式仍要加载,否则交互、响应式、滚动后内容会失效。重点不是“要不要加载”,而是“怎么加不阻塞”。
正确做法:
- 用
link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'":预加载+ onload切换,兼容性好,不阻塞渲染 - 避免
link rel="stylesheet"放在末尾:仍会阻塞首次绘制 - 不要用
document.write或fetch().then(insert)插入:触发同步重排,可能造成二次闪烁
示例片段(需配合内联关键CSS):
<link rel="preload" href="/styles/main.css" as="style" onload="this.onload=null;this.rel='stylesheet'"><noscript><link rel="stylesheet" href="/styles/main.css"></noscript>
noscript兜底是必须的——onload在禁用JS时不会执行,否则样式彻底丢失。
容易被忽略的细节:媒体查询、字体、缓存与调试
关键CSS不是“一次提取,永久有效”。页面结构、设备适配、字体加载策略稍有变动,就可能让内联样式失效或冗余。
重点关注:
- 媒体查询必须完整保留:比如
@media (min-width: 768px) { .nav { display: flex; } }若被漏掉,平板首屏导航就塌了 - 字体
@font-face规则不能进关键CSS:它们本身不参与布局绘制,且font-display: optional可能直接跳过加载 - CDN或代理层可能缓存了旧的HTML(含旧关键CSS),导致新CSS上线后首屏样式错乱——需要确保HTML缓存时效短于CSS更新周期
- 调试时别只看
Network标签:打开Rendering → Paint flashing,确认首屏区域是否真的一次绘制完成
最麻烦的点其实是动态内容:服务端渲染的首屏若含用户状态(如登录态.user-greeting),关键CSS提取必须基于真实用户场景生成,而不是用爬虫模拟的“游客页”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











