font-display: swap 是解决 fout 的基础起点,但闪烁主因是 fallback 与 web font 度量(宽高、行高、基线)不一致引发重排;需统一字体类型、启用 size-adjust/ascent-override、预加载时加 crossorigin 属性。

font-display: swap 是解决 FOUT 的唯一有效起点,不配它,其他优化全白搭。
为什么写了 font-display: swap 还在闪
不是 swap 失效,而是 fallback 字体和 Web Font 度量不一致导致重排——文字宽度、行高、基线一变,段落就“跳”。常见于中文字体混用西文 fallback(如 "Inter", "PingFang SC", sans-serif),或 fallback 里塞了 "Times New Roman" 这类衬线字体去匹配无衬线 Web Font。
- 检查
@font-face中是否漏了format("woff2"):浏览器可能因格式识别失败而忽略整个规则,font-display也就没生效 - 确认 fallback 链里所有字体都属于同一类型:中英文字体要分开兜底,比如
"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", sans-serif - 避免在 CSS 其他地方用
font-size或line-height强制缩放,这会让 fallback 和 Web Font 渲染时基线错位
preload 关键字体但没效果
预加载失败往往不是路径问题,而是 CORS 策略拦截——字体请求默认是匿名的,必须显式声明 crossorigin,否则浏览器静默丢弃响应。
-
<link rel="preload" href="fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>必须带crossorigin,哪怕字体同源 -
as="font"和type="font/woff2"缺一不可;写成as="fetch"或漏掉type,Chrome 会复用缓存但不触发字体解析 - preload 只对
font-display: swap或optional有效;设成block时,预加载反而可能延长阻塞时间
怎么让 swap 前后几乎不跳
靠 fallback 字体“假装”和 Web Font 一样高、一样宽。现代浏览器(Chrome 120+、Safari 17.4+)支持 OpenType 度量覆盖,但前提是字体文件本身嵌入了 OS/2 表,且你用了 woff2 格式。
- 先用
opentype.js查目标字体的typoAscender/typoDescender值 - 在
@font-face中加size-adjust或ascent-override,例如:ascent-override: 95%; descent-override: 25% - fallback 字体链里不要混用
"Georgia"和"Inter":字宽差异放大跳动,宁可全用无衬线
真正难的不是配好 font-display: swap,而是让 fallback 字体在视觉上“撑住场子”——它得足够像,又不能太像(否则用户看不出品牌字体已加载)。这个平衡点需要实测,尤其在 macOS 和 Windows 上渲染差异明显。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











