预加载字体必须同时满足三个条件:href路径与@font-face的src完全一致、as="font"、type属性正确;且需配置CORS头和匹配MIME类型,否则无效。

预加载字体必须用 <link rel="preload">,且 as="font" 和 type 缺一不可,否则浏览器不会以高优先级下载,甚至可能阻塞渲染或触发 CORS 错误。
为什么 <link rel="preload"> 加了却没生效?
常见失效原因不是写法遗漏,而是三个硬性条件未同时满足:
-
href指向的字体路径必须与 CSS 中@font-face的src完全一致(含协议、域名、查询参数) - 必须显式声明
as="font"—— 仅写rel="preload"不够,浏览器会按普通资源处理 - 必须加
type属性,例如type="font/woff2";若省略,Chrome 会降级为低优先级,Firefox 可能直接忽略 - 字体文件需配置正确的 CORS 响应头(
Access-Control-Allow-Origin: *或指定域名),否则即使预加载成功,CSS 加载时仍会因跨域被拒
<link rel="preload"> 放在哪儿最合适?
必须放在 <head> 内、所有引用该字体的 CSS <link> 或 <style> 之前。顺序错了等于白加:
- 如果放在 CSS 后面,浏览器解析到 CSS 时已开始下载字体,预加载请求可能被丢弃或重复
- 不建议放在
<body>或延迟脚本中 —— 预加载必须尽早触发,越晚越失去意义 - 多个字体要分别预加载,不能合并成一个
<link>;preload不支持多资源批量声明
WOFF2 和 WOFF 怎么选 type?
type 值必须和实际响应的 MIME 类型严格匹配,否则部分浏览器(如 Safari)会拒绝使用预加载结果:
- 服务端返回
Content-Type: font/woff2→ 写type="font/woff2" - 服务端返回
Content-Type: font/woff→ 写type="font/woff" - 不要凭文件后缀猜测:有些 Nginx 配置漏配 WOFF2 类型,导致返回
text/plain,此时即使写了type="font/woff2"也无效 - 可用
curl -I your-font.woff2检查真实响应头
预加载后字体还是闪动(FOIT/FOUT)?
预加载只解决下载时机问题,不控制字体就绪后的应用时机。仍需配合 CSS 策略:
- 用
font-display: swap在@font-face中声明,确保文本先用系统字体显示,等自定义字体加载完成再替换 - 避免在
@font-face中写font-display: block—— 它会让文本空白等待 3 秒,和预加载目标冲突 - 不要依赖 JS 动态插入
<link rel="preload">:DOM 解析前无法触发预加载,失去意义
最容易被忽略的是 CORS 头和服务端 MIME 类型 —— 这两个问题不会报明显错误,但会让预加载形同虚设。检查时优先抓包看字体请求的响应头,而不是只盯 HTML 是否写了 preload 标签。

















