font-display: swap 必须显式写在 @font-face 规则内,否则浏览器按 auto(等同 block)处理,导致文字空白 100ms 后最多等待 3 秒;它是唯一不改 HTML、不写 JS 即可实现文本“立刻可见”的方案,用系统字体先渲染,自定义字体就绪后替换,虽有重排风险但远优于白屏;正文类应优先选用 swap,且每个字重需独立声明并配 preload(含 crossorigin、as="font"、type="font/woff2")及 format("woff2")。

font-display: swap 必须显式写在 @font-face 里
不写 font-display,浏览器就按 auto 处理,实际等同于 block:文字先空白约 100ms,再最多等 3 秒加载字体,失败才 fallback。在线预览类页面一打开就看到白屏段落,不是加载慢,是浏览器在守规矩。
swap 是唯一不改 HTML、不写 JS 就能让文本「立刻可见」的方案:系统字体先撑开布局,等自定义字体就绪后替换。重排风险存在(尤其中英文混排或字宽差异大时),但比白屏好十倍。
- 别用
block,也别省略font-display -
fallback和optional适合非关键文本(如装饰性标题),正文类优先选swap - 每个要用的字重(如
400、700)都得有独立的@font-face块,且都显式写上font-display: swap
preload 字体必须带 crossorigin 属性
<link rel="preload"> 是唯一能在 HTML 解析阶段就触发字体下载的手段,但它对属性极其敏感:缺 crossorigin,哪怕字体跟页面同源,浏览器也直接跳过该请求。
正确写法只有一种组合:as="font" + type="font/woff2" + crossorigin(值为空即可,crossorigin="" 或 crossorigin 都行)。
立即学习“前端免费学习笔记(深入)”;
- 没写
crossorigin→ Network 面板里看不到请求,或 Priority 显示为lowest - 写了
crossorigin但字体服务没配 CORS 响应头(如Access-Control-Allow-Origin: *)→ 控制台报CORS error - 只
preload首屏确定用到的字重,比如Inter-Bold.woff2,别把整套 variable font 全 preloaded
href 路径必须和 @font-face src 完全一致
预加载本身不启用字体,必须在 CSS 中通过 @font-face 注册,且 src 的 URL 要与 <link> 的 href 完全匹配——包括版本参数、CDN 域名、查询字符串。
例如:若 CSS 中用了 url('/fonts/inter-bold.woff2?v=1.2'),那么 <link> 的 href 也必须带相同参数,否则浏览器不会复用预加载结果,而是发起新请求。
- 常见错误是 CDN 域名不一致(如预加载用
https://cdn.example.com,@font-face 用/fonts/...) - 构建工具自动注入版本哈希时,容易漏同步
<link>的href - 服务器需对
.woff2文件返回Content-Type: font/woff2,否则部分浏览器拒收
验证 preload 是否真正生效
打开浏览器开发者工具 → Network 面板,筛选 font,刷新页面:
- 预加载的字体应出现在早期(通常在 HTML 解析阶段就发起),Status 显示
200或206,Initiator 标为preload - 检查 Timing 标签页,确认 Start Time 非常靠前,Download 时间短且无排队延迟
- 若字体未出现或显示
cancelled,常见原因是crossorigin缺失、as值错误,或服务器未返回正确的 CORS 头 - Chrome DevTools Network 面板里,
preload请求显示为Priority: high,而普通样式表是Priority: medium——这是验证是否生效的最快方式
最容易被忽略的是:即使所有标签都写对了,只要 <link rel="preload"> 没放在 <meta charset> 和 <title> 之后、其他 <link rel="stylesheet"> 之前,它就大概率被浏览器跳过——结构位置比语法更重要。



















