javascript 不直接加载字体,而是通过配合 css(font-display: swap + preload)和 fontface api/fontfaceobserver 实现精准控制与兜底,避免 fout/foit,禁止动态改 font-family 引发二次闪烁。

JavaScript 本身不直接加载字体文件,但能配合 CSS 和 HTML 协同优化字体加载流程,从而避免文字闪烁(FOUT/FOIT)。关键不是“用 JS 加载字体”,而是用 JS 做精准控制和兜底处理——让字体切换更可控、更平滑。
用 font-display: swap + preload 组合打基础
这是防闪烁最核心的 CSS 层策略,JS 不替代它,但要确保它生效:
- @font-face 中必须写 font-display: swap:让浏览器在自定义字体未就绪时,先用备用字体显示文本,加载完成再替换,避免空白(FOIT)
- 要严格配对:href 路径必须与 @font-face 的 src 完全一致(含大小写、查询参数),且加 as="font"、crossorigin、type="font/woff2"
- preload 标签必须放在所有 CSS 引入之前,否则浏览器解析到样式时已发起默认字体请求,预加载就失效了
用 FontFace API 主动监听与控制时机
当需要更精细干预(比如首页标题等关键文案),可用 JavaScript 的 FontFace API 手动加载并监听状态:
- 创建 FontFace 实例,调用 .load() 返回 Promise,明确知道字体何时可用
- 加载成功后,用 document.fonts.add() 注册字体,再通过 CSS 类或 style 动态启用,避免全局字体切换引发的批量重排
- 可结合 loading 状态,在字体就绪前给容器加 loading 类(如 opacity: 0.8),就绪后再移除,视觉过渡更自然
用 FontFaceObserver 做降级与容错
原生 FontFace API 兼容性有限(IE 不支持),生产环境建议用轻量库 FontFaceObserver:
- 它封装了跨浏览器字体加载检测逻辑,返回 Promise,比轮询更可靠
- 可设置超时(如 3s),超时后自动 fallback 到系统字体,并记录埋点,便于后续优化
- 支持监听多个字体族,适合多字重、多语言场景,避免某一个字体失败导致整套失效
避免 JS 动态改 font-family 引发二次闪烁
有些项目会在 DOMContentLoaded 后用 JS 设置 body 字体,这反而会触发额外的 FOUT:
- 字体声明应写在 CSS 中,由浏览器原生解析和应用;JS 只负责“增强”,不负责“首次启用”
- 如果必须动态切换(如主题切换),优先用 CSS 自定义属性(--font-main)+ class 切换,而非直接改 style.fontFamily
- 切换前可加 will-change: font-family 或临时 visibility: hidden,减少重排影响
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











