font-display: swap 是避免 foit 的核心 css 策略,需正确配置 @font-face、预加载及 js 监听就绪来实现可控字体替换与布局稳定。

JavaScript 本身不加载字体,也不直接控制字体渲染时机。避免文字闪烁(FOIT)的核心是 font-display: swap 这个 CSS 策略,JS 的作用是配合它做精准控制和兜底——比如监听就绪、切换状态、降级处理,而不是替代它。
必须写对 @font-face 才生效
font-display 只在 @font-face 规则内部起作用,写在普通 CSS 类或 JS 里完全无效。常见错误包括:
- 漏掉
format("woff2"):Safari 和旧 Edge 会直接忽略整条规则,退回到默认阻塞行为(FOIT) - 拼错值,比如写成
swop或swap::整条@font-face被浏览器丢弃,字体压根不注册 - 只给 Regular 字重加了
font-display: swap,而 Bold、Medium 没单独声明:粗体仍走 auto,FOIT 复现
preload 必须严格配对且前置
<link rel="preload"> 不是锦上添花,而是让 swap 真正起效的前提。否则浏览器可能在解析完 CSS 后才发起字体请求,“swap 窗口”已过,用户看到的仍是延迟替换甚至 FOIT。
- href 路径必须与
@font-face中src完全一致(含大小写、查询参数) - 必须带
crossorigin属性,否则跨域字体预加载失败 - 必须写
as="font"和type="font/woff2",否则浏览器不按字体资源优先级处理 - preload 标签要放在所有 CSS
<link>之前,否则被浏览器跳过
用 JS 监听就绪,不是为了加载,而是为了可控切换
font-display: swap 解决了“立刻显示”,但没解决“何时可安全应用动画/布局调整/字体族切换”。这时 JS 才真正派上用场:
- 用
document.fonts.load()或FontFace API主动加载并监听完成 - 在
active回调中添加fonts-loaded类,触发 CSS 动画或启用高保真排版样式 - 避免直接动态改
font-family:这会引发二次渲染和闪烁,应靠 class 切换 + CSS 过渡控制 - 不推荐用 WebFont Loader 默认的 class 注入机制,它和原生
swap行为冲突,建议关闭classes: true改用回调
fallback 字体链决定是否“跳”
swap 不等于无感切换。如果备用字体和 Web 字体的 x-height、字宽、行高差异大,替换瞬间就会触发布局偏移(CLS),表现为文字下移、换行点突变。
- 选同类型 fallback:如
"Inter", "system-ui", -apple-system, "Segoe UI", sans-serif - 避免混搭衬线与无衬线,例如
"Georgia", "Inter"—— 字宽差常超 20% - 中文字体务必子集化,否则体积大(常 ≥2MB),swap 替换延迟更明显,跳动更剧烈
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











