rel="preload" + as="font" 能显著缓解字体闪烁,但必须同时满足as="font"、crossorigin、type="font/woff2"且href与@font-face完全一致,否则预加载静默失效。

rel="preload" + as="font" 能显著缓解字体闪烁,但写错一个属性就等于没写——最常失效的原因是漏掉 crossorigin 或 as="font" 值填错。
为什么加了 preload 还在闪?
不是浏览器不支持,而是预加载被静默跳过了。常见原因包括:
-
crossorigin缺失:字体请求默认是匿名的,CORS 策略会直接丢弃响应,Network 面板里看不到请求,也不报错 -
as值写成"fetch"或"script":浏览器按普通资源处理,不提升优先级,不进字体缓存 -
href和后续@font-face中src的 URL 不完全一致(比如少了个?display=swap):预加载的资源不会被复用 - 用了
type="font/woff"却实际返回font/woff2:MIME 类型不匹配,浏览器可能降级或忽略
as="font" 必须配哪些属性才生效?
只写 <link rel="preload" href="/fonts/inter.woff2" as="font"> 是无效的。必须同时满足:
-
as="font":强制浏览器走字体加载管线(高优先级、进 font cache) -
crossorigin:哪怕字体同域也得加,否则 CORS 拦截;第三方字体(如 Google Fonts)必须写crossorigin="anonymous" -
type="font/woff2":明确 MIME 类型,避免格式识别失败;不要写type="application/font-woff2",它不是标准值
正确示例:<link rel="preload" href="/fonts/Inter-Bold.woff2" as="font" type="font/woff2" crossorigin>
preload 和 font-display: swap 怎么配合?
两者不是替代关系,而是分工协作:
-
font-display: swap写在@font-face里,控制渲染行为:立刻用 fallback 渲染,等字体就绪再替换 -
rel="preload"提前拉取字体文件,缩短“等待就绪”的时间窗口 - 如果只设
swap不preload,弱网下仍可能延迟 400ms+ 才替换;只preload不swap,则字体未就绪时文字仍是空白(FOIT) - 注意:
preload后仍需正常声明@font-face,它不代替 CSS 字体注册
容易被忽略的静默失效点
最麻烦的问题不是报错,而是“看起来写了,其实没起作用”:
- Network 面板中请求的
Accept请求头不是font/woff2→ 检查as和type是否匹配 - Response Headers 里
Content-Type是text/plain或空 → 服务端没配对 MIME 类型,type属性白写了 - 字体文件路径用了相对 URL,但页面部署在子路径(如
/app/),而href写的是fonts/xxx.woff2→ 实际请求变成/app/fonts/xxx.woff2,404 了却没注意 - 在动态插入的 HTML 片段里写
preload(如 innerHTML 赋值)→ Chrome 只认静态写在里的声明
真正要盯住的,是 Network 面板里那个字体请求的 Priority 是否为 Highest,以及 Headers 标签页中 Accept 和 Content-Type 是否严丝合缝。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











