必须放在 中,否则会触发 FOUC;避免阻塞需用 media 条件加载、preload 动态注入、内联关键 CSS,并确保 CDN 与缓存配置正确。

为什么 必须放在 里
浏览器解析 HTML 是从上到下流式进行的,遇到 时会立即发起 CSS 请求,并**阻塞后续 HTML 解析与渲染**(直到该 CSS 加载并解析完成)。如果把它错放到 底部,页面 HTML 已解析完、DOM 构建完毕,但样式还没加载,就会先渲染出「无样式的白屏内容」,再突然重绘——这就是常说的 FOUC(Flash of Unstyled Content)。
所以不是“建议”放 ,而是**必须放**,这是避免样式延迟应用的底线。
如何避免 阻塞首屏渲染
真正影响首屏体验的,不是“放哪”,而是“加载多慢”。关键在减少阻塞时间:
- 用
media属性做条件加载,比如打印样式:—— 浏览器不会为它阻塞屏幕渲染 - 对非首屏必需的 CSS(如模态框、图表组件样式),改用
rel="preload"+ 动态注入:(注意:需配合onload回调切换rel,否则只是预加载不生效) - 慎用
@import:它在 CSS 文件内部使用时,会引发串行加载,比多个更慢;HTML 中禁止用
内联 vs 外链:什么该内联
内联 确实免去一次 HTTP 请求,但无法缓存,且体积大会拖慢 HTML 解析。只适合极小、首屏强依赖、且变动极少的 CSS:
立即学习“前端免费学习笔记(深入)”;
- 首屏关键样式(Critical CSS),比如标题字体、按钮基础尺寸、折叠导航的初始状态
- 避免内联整个
normalize.css或框架基础样式——它们体积大、复用率高,外链 + CDN 缓存更优 - 构建时用工具(如
critters或PurgeCSS + critical)自动提取并内联,别手写;手写容易漏、难维护
HTTP/2 和 preload 能否替代传统
HTTP/2 的多路复用能缓解多个 的连接开销,但**不改变 CSS 阻塞渲染的本质**;preload 只是提前发起请求,仍需手动挂载为样式表。实际优化路径很明确:
- 优先合并、压缩、Gzip/Brotli 压缩 CSS 文件
- 用
替代普通,可略微提升加载优先级(尤其在网络慢时) - 但
preload不是银弹:滥用会导致资源竞争,比如预加载了非首屏 CSS,反而挤占首屏 JS/CSS 的带宽
最常被忽略的一点:CSS 文件路径是否走 CDN?一个未开启缓存或跨域未配 CORS 的外链 CSS,加载失败时会静默阻塞数秒,比慢还致命。











