必须放在顶部,因为浏览器自上而下解析html,只有提前声明才能在解析早期触发字体下载;若被css或js阻塞、缺as="font"或crossorigin、路径与@font-face不一致,预加载即失效。

字体加载不是纯 CSS 问题,它和 HTML 结构、资源加载顺序强耦合。不调整结构,font-display: swap 也可能失效或触发白屏。
为什么 <link rel="preload"> 必须放在 顶部
浏览器解析 HTML 是自上而下流式进行的。<link rel="preload" as="font"> 只有在解析到它时才会提前发起字体请求;如果它被 CSS 或 JS 阻塞(比如写在 <link rel="stylesheet"> 后面),就失去预加载意义。
-
as="font"必须显式声明,否则浏览器当它是普通资源,不会进字体加载队列 - 必须加
crossorigin属性,哪怕字体同源——woff2 解析器强制要求 CORS 上下文 - 路径要和
@font-face中src的 URL 完全一致(含协议、域名、路径大小写)
@font-face 声明位置影响字体可用时机
CSS 文件里 @font-face 的位置本身不影响加载,但它的「首次被用到」时机由 HTML 中第一个使用该 font-family 的元素决定。如果这个元素在 DOM 尾部,浏览器可能延迟解析字体规则。
- 把关键字体的
@font-face放在 CSS 文件最前面,避免被后续规则阻塞解析 - 不要在
@import的 CSS 文件里定义@font-face——导入是异步的,字体声明可能滞后 - 若用
type="module"脚本动态注入样式,@font-face生效时间不可控,首屏文字大概率 fallback
内联关键 CSS + 字体声明能绕过 FOIT
服务端渲染或构建时提取首屏所需字体声明,内联进 的 <style></style>,可确保浏览器在解析 HTML 早期就拿到 @font-face 和 font-display 配置。
- 内联内容体积别超 14KB(HTTP/2 下仍建议控制),否则影响 TCP 初始拥塞窗口利用
- 只内联首屏必需的字体(如标题、导航文字用的那 1–2 个字重),别把整套字体都塞进去
- 内联后仍需配
font-display: swap,否则内联 CSS 里没它,浏览器照样按block行为处理
真正卡住字体显示的,往往不是文件大小,而是 HTML 结构里资源声明的先后顺序和执行上下文。一个没 crossorigin 的 preload,或一个藏在 @import 深处的 @font-face,都可能让 swap 形同虚设。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











