内联首屏关键css是压低fcp最立竿见影的办法,需基于真实移动端视口(如375×667)自动提取、过滤@font-face/@keyframes/不匹配媒体查询样式,置于最顶部、体积≤14kb(gzip后)、minify,并移除原阻塞link,非关键css用media="print" onload切换或domcontentloaded后动态加载。

直接把首屏真正用到的 CSS 写进 HTML 的 <style></style> 标签里,是压低首次内容绘制(FCP)最立竿见影的办法。关键不在“内联”这个动作本身,而在于内联的内容是否精准、体积是否可控、位置是否正确。
精准提取首屏实际生效的样式
不能靠肉眼猜,也不能用桌面端宽屏(如 1920×1080)去提取后塞给手机用——那样会混入大量 @media (min-width: 1200px) 规则,白占体积还不起作用。
- 模拟真实首屏视口:移动端优先,设为
width: 375, height: 667(iPhone SE)或width: 414, height: 896(iPhone 12) - 用工具自动分析:Vite 项目推荐
vite-plugin-critical,Webpack 用critters,静态站可用critical CLI - 必须过滤掉不参与首屏渲染的部分:
@font-face、@keyframes、display: none元素相关样式、未命中媒体查询的规则 - 别手动写:容易漏掉
:hover、::before、暗色模式@media (prefers-color-scheme: dark)等真实生效的规则
内联位置和体积要卡死
哪怕样式全对,放错地方或太大,反而拖慢首屏。
-
<style></style>必须放在最顶部,且前面不能有任何<script></script>、<link>或含@import的样式块 - 体积控制在 14KB 以内(gzip 后):超了会导致 HTML 主文档变大、TTFB 上升、解析开销增加
- 开发阶段建议加硬性校验,比如
critters配置maxSize: 14336 - 输出前必须压缩(minify),剔除注释、空格、重复声明
非关键 CSS 要延迟加载但不能闪屏
只内联关键部分,不代表扔掉其余样式——得让浏览器“先跳过,后激活”,避免 FOUC(闪白)或样式抖动。
- 标准做法:
<link rel="stylesheet" href="non-critical.css" media="print" onload="this.media='all'">——默认不触发解析,加载完成再启用 - 更可控方式:在
DOMContentLoaded后用 JS 动态插入,或配合requestIdleCallback避免抢占主线程 - 禁用
rel="preload"单独加载 CSS:没配as="style"和onload切换rel,预加载不会进入 CSSOM,等于无效 - 记得移除原来那个阻塞型的
<link rel="stylesheet">,否则照样卡住渲染
缓存策略要同步调整
关键 CSS 内联后,样式就随 HTML 一起传输了,HTML 文件本身成了样式缓存单元。
- 缩短 HTML 的缓存时间,比如
Cache-Control: max-age=3600,否则样式更新用户无法及时看到 - 非关键 CSS 文件仍可长期缓存(
max-age=31536000),配合内容哈希确保更新有效性 - 服务端注意:内联样式无法被 CDN 单独缓存,体积越大,每次 HTML 变更传输成本越高
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











