font-display 是 @font-face 中控制字体加载时文本渲染策略的描述符,用于避免 FOIT 导致首屏空白;它不加速下载,只优化可见内容呈现时机,swap 和 optional 最利于 FCP。

font-display 是什么,为什么它能影响首次渲染
font-display 是 CSS @font-face 规则里的一个描述符,控制字体加载期间的文本渲染行为。浏览器默认会隐藏文字(FOIT),等字体加载完成才显示,导致首屏空白或布局跳动。设置合适的 font-display 值,能让浏览器在字体未就绪时先用系统字体渲染,避免阻塞首次内容绘制(FCP)。
关键不是“让字体更快”,而是“不让字体拖慢页面可见内容的出现”。它不改变字体文件下载速度,只改变渲染策略。
font-display 的可选值及真实表现差异
四个常用值中,只有 swap 和 optional 对首屏性能最友好,但适用场景不同:
-
swap:立即用后备字体显示文字,字体加载完成后无感替换(有轻微重排风险,但用户感知弱) -
optional:只在字体能在 100ms 内加载完成时使用;否则全程用后备字体(最激进,适合非品牌关键字体) -
fallback:类似swap,但替换窗口更短(约 100ms),之后即使字体加载完也不替换 -
block(默认):强制等待字体,可能造成 3s+ 白屏,尤其在弱网下
注意:optional 在 Safari 14.1+ 才稳定支持,旧版 Safari 会退化为 block,需结合 @supports 检测或降级处理。
立即学习“前端免费学习笔记(深入)”;
如何安全地在 @font-face 中启用 font-display
直接加在 @font-face 块里即可,但要注意优先级和 fallback 配置:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var-latin.woff2') format('woff2');
font-weight: 100 900;
font-display: swap; /* 必须写在这里 */
font-style: normal;
}常见错误:
- 把
font-display写在普通 CSS 规则里(如body { font-display: swap; })——无效 - 多个
@font-face声明中混用不同font-display值,导致同族字体行为不一致 - 没配好
font-family回退链,例如font-family: 'Inter', sans-serif;中sans-serif在某些系统上渲染过粗或过细,影响可读性
配合 preload 和字体子集进一步压缩加载压力
font-display 解决的是“怎么显示”,但字体文件本身仍要下载。若字体过大或未优化,仍会浪费带宽、触发多余请求:
- 用
<link rel="preload">提前拉取关键字体(仅限swap或fallback场景,optional不需要) - 对中文等大字符集,务必做子集切分(如只含标题用字),否则单个 WOFF2 文件超 500KB 很常见
- 避免在 CSS 中同时声明
.woff和.woff2,现代浏览器都支持.woff2,多格式会增加解析开销
真正卡顿的从来不是“字体要不要换”,而是“字体要不要加载”——font-display: optional 加子集 + preload,才是移动端首屏保底方案。但别忘了测试 iOS 微信内置浏览器,它的字体加载逻辑和标准 Safari 并不完全一致。



















