font-display: swap 是图标字体的底线配置,它让浏览器立即用系统字体占位渲染,待字体加载完自动替换,避免 FOIT 白屏,虽有轻微重排但体验优于空白等待。

font-display: swap 是图标字体的底线配置
不加 font-display,Font Awesome 这类图标字体默认走 block 行为:文字/图标先空白约 100ms,再等最多 3 秒加载字体,失败才 fallback——这就是 FOIT(无样式文本闪白)。用户看到的是“图标消失→突然出现”,尤其在弱网或首次访问时极明显。
必须显式写 swap:
@font-face {
font-family: "Font Awesome 6 Free";
src: url("webfonts/fa-solid-900.woff2") format("woff2");
font-display: swap;
}它让浏览器立刻用系统默认字体(如 serif)占位渲染,图标文字先显示为方块或乱码,等 woff2 加载完自动替换。虽有轻微重排,但比白屏体验好得多。
-
fallback适合非关键图标(如装饰性角标),但首屏按钮、导航图标别用——超时后永远不换 -
optional基本不用:字体只在缓存命中或网络极快时加载,对图标这种强可见元素不可控 - 别信
auto:各浏览器实现不一,Chrome 当前仍等同block
preload 必须带 crossorigin 才生效
仅写 <link rel="preload" href="webfonts/fa-solid-900.woff2" as="font"> 是无效的。浏览器会静默忽略该请求,Network 面板里看不到 high 优先级请求。
立即学习“前端免费学习笔记(深入)”;
正确写法必须三要素齐备:
<link rel="preload" href="webfonts/fa-solid-900.woff2" as="font" type="font/woff2" crossorigin>
crossorigin 属性不能省——哪怕字体跟 HTML 同源。这是字体资源的 CORS 特殊要求,和图片、脚本不同。
- 只对首屏确定要用的图标字体 preload,比如
fa-solid-900.woff2;fa-brands-400.woff2若只在个人中心页用,就别 preload - preload 不替代
@font-face:两者必须共存,一个负责提前取,一个负责声明和应用 - IE 不支持 preload,但 Font Awesome 7 已不兼容 IE,可放心用
避免全量 CSS 加载导致图标延迟
直接引入 css/all.css(1.2MB)会让图标字体加载被卡在巨量 CSS 解析之后。Lighthouse 常报“未优化的关键资源”,首屏图标可能晚 400ms+ 才出现。
更合理的做法是按需拆分:
- 只引入当前页用到的图标 CSS:
css/fontawesome.css+css/solid.css(若只用实心图标) - 用 JS 按需注册图标(Font Awesome 7 推荐):
import { faUser, faHome } from '@fortawesome/free-solid-svg-icons';,再library.add(faUser, faHome) - SVG Sprite 方案(适合图标固定且数量少):把图标打包成单个 SVG 文件,用
<use href="#icon-home"></use>引用,完全绕过字体加载逻辑
注意:JS 按需方案依赖 defer 脚本,否则同步执行会阻塞 HTML 解析。
检测字体是否加载失败?别靠肉眼
即使写了 swap 和 preload,字体仍可能因 404、CORS 错误、路径错误而加载失败。用户看到的只是方块或空格,你却不知道问题在哪。
用 document.fonts.load() 主动探测:
document.fonts.load('1em "Font Awesome 6 Free"').then(() => {
document.documentElement.classList.add('fa-loaded');
}).catch(() => {
console.warn('FontAwesome font failed to load');
});配合 CSS 可做降级:
.fa::before { content: '⚠'; }
.fa-loaded .fa::before { /* 正常图标内容 */ }- 这个检测必须在
@font-face声明之后、且字体实际被用到之前执行 - 不要在
DOMContentLoaded里才调,应尽早插入 inline script,确保在首屏渲染前完成判断 - CDN 字体若未配好 CORS 头,
load()会直接 reject,这是最快速暴露配置问题的方式
真正卡住图标的从来不是字体文件大小,而是加载时机和容错机制。swap、preload、按需引用、主动检测这四步缺一不可,漏掉任一环,用户看到的就是闪烁、空白或方块——而这些问题在线上环境里,往往要等用户截图反馈你才意识到。


















