font-display: swap 是唯一能真正防阻塞的起点,它强制浏览器放弃等待、立刻用 fallback 渲染而非卡住3秒空白(foit);必须写在@font-face内才生效,写在class、style、@supports或js中均无效,且需配合format("woff2")、preload(带crossorigin/as="font"/type)及度量匹配的fallback字体链。

font-display: swap 是唯一能真正防阻塞的起点,不配它,后续所有优化都无效——它让浏览器放弃等待,立刻用 fallback 渲染,而不是卡住 3 秒空白(FOIT)。
为什么 font-display 必须写在 @font-face 里
浏览器只认 @font-face 规则内部的 font-display。写在 class、style 属性、@supports 块甚至 JS 的 element.style.fontDisplay 上,全都不生效。
- 常见错误:多个
@font-face共用同一个font-family名,但只给 Regular 写了font-display: swap,Bold 和 Italic 仍按默认block等待,导致部分文字白屏 - 另一个坑:用
@import引入字体 CSS,误以为它能继承加载策略——其实@import不带任何控制能力,浏览器照旧卡住 - 漏写
format("woff2")会导致整个@font-face被忽略(尤其旧版 Safari/Edge),font-display自然失效
preload 加了却没效果?检查这三个硬性条件
预加载不是加了 link 就完事。字体请求是匿名的,CORS 策略会静默拦截未声明 crossorigin 的响应。
- 必须带
crossorigin属性:<link rel="preload" href="/fonts/inter-bold.woff2" as="font" type="font/woff2" crossorigin> -
as="font"和type="font/woff2"缺一不可;写成as="fetch"或漏掉type,Chrome 会复用缓存但不触发字体解析 -
preload只对swap或optional有效;设成block时,预加载反而延长阻塞时间
fallback 字体链怎么写才不跳
写了 swap 还“闪一下”,本质是 fallback 和 Web Font 度量不一致:字宽、x-height、行高、基线一变,段落就重排(FOUT)。这不是 bug,是 layout shift 的必然结果。
- 中英要分开兜底:
"Inter", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif—— 避免用"Times New Roman"这类衬线字体去匹配无衬线 Web Font - 统一类型优先:全用无衬线(如
"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI"),别混"Georgia", "Inter" - 路径或协议问题常被忽略:本地开发用
file://协议时,字体请求会被跨域拦截,必须起 HTTP 服务(如npx serve)
真正难的不是把 font-display: swap 写进去,而是让 fallback 字体在视觉上“撑住场子”——它得足够像,又不能太像;度量值匹配比格式压缩更重要,而这点恰恰最容易被跳过。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











