预加载字体必须显式声明crossorigin,且href与@font-face的src路径严格一致,并正确设置type和服务端CORS响应头,否则会导致重复请求、FOIT加剧或字体不渲染。

as="font" 必须配 crossorigin,不是可选
浏览器对字体资源的加载强制执行 CORS 策略,哪怕字体和 HTML 同源,crossorigin 也必须显式声明。不加或写错,预加载会成功下载,但后续 @font-face 无法复用该响应——结果是重复请求、FOIT 加剧,甚至字体完全不渲染。
正确写法只有两种:
-
crossorigin="anonymous":最常用,不发送 Cookie 或认证凭据;服务端只需返回Access-Control-Allow-Origin: *或精确域名即可 -
crossorigin=""(空字符串):等价于anonymous,语义更轻,但效果一致
绝对不要写 crossorigin="use-credentials",除非你明确知道字体托管在需登录态鉴权的私有 CDN 上——这种场景极少见,且服务端必须同步返回 Access-Control-Allow-Credentials: true 和精确的 Access-Control-Allow-Origin,漏一条就静默失败。
href 和 @font-face 的 src 必须一字不差
预加载生效的前提是路径完全匹配:href 值必须和 CSS 中 @font-face 的 src 声明严格一致,包括协议、域名、路径、查询参数(如 ?v=1.2)、大小写。
立即学习“前端免费学习笔记(深入)”;
常见失效点:
- CSS 里写的是
url("/fonts/inter.woff2?v=2"),但<link>的href是/fonts/inter.woff2(少参数) - 服务器重定向了字体路径(比如 302 到带 hash 的版本),但预加载仍指向原始 URL
- 开发环境用
http://,生产环境切到https://,而href没同步更新
验证方法:在 Chrome DevTools 的 Network 面板中,找到该字体资源,点开 Headers → Request URL,和你写的 href 逐字符比对。
type 属性不是摆设,尤其对 Firefox
type 虽然在 Chrome 中影响较小,但在 Firefox 中缺省会导致预加载被忽略或降级为低优先级。必须按 MIME 类型准确填写:
- .woff2 →
type="font/woff2" - .woff →
type="font/woff" - .eot →
type="application/vnd.ms-fontobject" - .ttf →
type="font/ttf"
别写 type="text/plain" 或留空——这会让 Firefox 直接跳过该 <link>,Network 面板里根本看不到请求发起。
服务端 CORS 响应头不能只靠 Nginx add_header
即使前端写了 crossorigin="anonymous",如果字体文件响应头里没有 Access-Control-Allow-Origin,预加载也会静默失败(Chrome 控制台可能只报一句模糊的 Font from origin 'xxx' has been blocked)。
关键检查项:
- 字体文件实际响应头中必须包含
Access-Control-Allow-Origin: *(公共字体)或Access-Control-Allow-Origin: https://your-domain.com(私有字体) - 如果用了
crossorigin="use-credentials",还必须返回Access-Control-Allow-Credentials: true,且Access-Control-Allow-Origin不能为* - Nginx 的
add_header默认不作用于 404 或 304 响应,确保字体路径真实存在并返回 200
用 curl -I https://cdn.example.com/fonts/inter.woff2 直接查响应头,比依赖浏览器更可靠。
最容易被忽略的一点:预加载本身不触发字体渲染,font-display: swap 仍得在 @font-face 中显式声明,否则即使预加载提前了 500ms,用户仍可能面对长时间空白文本。



















