事情本身不复杂,线索都在日志里。head 里给主字体写了 preload,Network 面板里同一个 woff2 出现两条请求,一条标着 preload,一条来自 CSS。首屏比不加 preload 还慢了 180ms。控制台有一条警告,提示预加载的资源没有被使用。
第一反应是「preload 的地址和 CSS 里引用的地址差了一个版本参数」,验证下来不成立。
这类报错背后常见的原因有几处,逐个排除就行。preload 少了 crossorigin 属性,匿名预加载和 CSS 里的字体请求模式不同。少数情况下是字体跨域但没有返回 Access-Control-Allow-Origin,浏览器无法复用。
还有一种情况,缓存键按请求模式区分,两次请求各存了一份。
上来先在 Network 里按类型筛字体,看是否有两条同名请求
给 preload 补上 crossorigin 与正确的 as 类型
<link rel="preload" href="/font/main.woff2" as="font" type="font/woff2" crossorigin>
接着确认字体响应的跨域头
curl -sI https://static.example.com/font/main.woff2 | grep -i access-control
末了统一模板里 preload 与 CSS 的字体地址
grep -rn 'woff2' templates/ static/css/ | head
恢复的判定其实很直接。字体只下载一次,控制台的未使用预加载警告消失,首屏渲染时间回落约 0.2 秒。
这里还有个坑。字体的 preload 和图片不一样,crossorigin 不能省,少了它浏览器会把两次请求当成两个不同的资源。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。
