放在 更安全,因其能阻塞 HTML 解析以确保样式就绪、避免 FOUC,且支持预加载、媒体查询和 rel="preload" 等机制;放 仅适用于 JS 动态插入的非关键 CSS。

为什么 放在 里更安全
浏览器解析 HTML 是从上到下流式进行的,遇到 时会发起 CSS 请求,并**阻塞后续 HTML 解析与 DOM 构建**(直到该 CSS 加载并解析完成)。放在 中能确保样式在页面内容渲染前就绪,避免 FOUC(Flash of Unstyled Content)——也就是页面先弹出无样式的白板,再突然“跳”成带样式的状态。
常见错误现象: 不是绝对禁止,而是要明确知道你在做什么、承担什么代价。唯一被广泛接受的例外是「非关键 CSS 的异步加载」——比如打印样式、暗色主题切换器的备用样式、或仅用于某个第三方组件的隔离样式。 这时通常配合 JavaScript 控制加载时机,例如: 立即学习“前端免费学习笔记(深入)”; 真实陷阱: 真正兼顾性能与体验的做法,不是纠结“放 head 还是 body”,而是拆分:把首屏必需的 CSS 提取出来,用 示例结构: 这个模式下, 放在 底部,但页面已有大量 等元素被解析并尝试渲染,此时浏览器发现没有可用样式规则,只能用默认样式画一遍;等 CSS 终于加载完,再重绘一次。用户肉眼可见“闪一下”。
中的 有预加载优化(如 preload scanner),能提前发起请求 在 中可被 或媒体查询(media="print")正确识别和延迟加载
rel="preload" 配合 as="style",也必须放在 ,否则无效
放在 的少数合理场景
在 里,否则仍会阻塞解析media 设为无效值(如 media="not all"),等需要时再改回 media="print" 或 media="all"
内联
标签的位置影响比 更直接 是同步解析执行的,无论放哪都会立即阻塞 HTML 解析。但它没有网络请求开销,所以位置选择核心在于「作用域可见性」和「维护成本」。
:样式对整个文档有效,符合语义直觉;但若只用于页脚某个组件,会导致全页面都多加载一段无用 CSS 某个元素上方(如紧贴 前):CSS 规则只对后续节点生效(因为 CSS 选择器匹配基于 DOM 树,而非声明顺序),但容易误判“它到底管不管用”@import(不推荐),必须放在 开头,且会引发额外阻塞,比 更慢 放在 中间,结果发现 .header { color: red; } 并没让顶部 变红——因为那段 出现在 元素之后,而 CSS 不会向上匹配已解析的节点。现代实践:关键 CSS 内联 + 剩余 CSS 异步加载
内联在 ;其余 CSS 用 提前拉取,再通过 onload 注入或 JS 动态挂载。
onload 回调中把 rel="preload" 改成 rel="stylesheet",才能真正应用样式this.onload=null 是防重复执行,尤其在某些旧版 Safari 中可能触发多次 是兜底,确保禁用 JS 时仍能加载主样式 的物理位置仍在 ,但逻辑上实现了“非阻塞加载”。硬塞进 只会让问题更难调试。











