Link Preload:快速加载关键字体资源

作者:技术拾光时间:2026-06-17 08:23:07浏览:478

根本原因其实很简单:浏览器压根没把这个 preload 请求当成字体来处理。要么是 as="font" 没写对,要么 crossorigin 属性漏了,再不然就是 href 和 @font-face 里的 src 路径对不上。这三个错误里只要犯一个,你写的 preload 就基本等于废了。 为什么字

根本原因其实很简单:浏览器压根没把这个 preload 请求当成字体来处理。要么是 as="font" 没写对,要么 crossorigin 属性漏了,再不然就是 href 和 @font-face 里的 src 路径对不上。这三个错误里只要犯一个,你写的 preload 就基本等于废了。

Link Preload:快速加载关键字体资源

为什么字体 preload 写了但 FOIT/FOUT 还在

相信不少人都遇到过这种情况:明明在 HTML 里加上了 ,但打开页面时,字体还是一闪而过,FOIT 或者 FOUT 依然存在。问题出在哪?

第一个坑:as="font" 没写对。很多人以为随便写个 as="woff2" 就行了,或者干脆不写。但浏览器看到这种写法,直接把它当普通资源请求处理,根本不按字体逻辑来。

第二个坑:crossorigin 属性没写。哪怕字体和你的 HTML 文件是同一个域名,浏览器加载字体时也默认走的是匿名 CORS 模式。如果你漏了这个属性,浏览器把字体文件下载完,也不会把它缓存给 @font-face 用。这不是 Bug,是浏览器的安全策略。

第三个坑:href 路径不一致。这个最容易被忽略。你在 preload 里写的路径,必须和 @font-face 的 src 完全一样——包括协议、域名、路径,甚至连后面的查询参数(比如 v=2.1)都要一字不差。差一个字符,浏览器就不会复用缓存,等于白忙活。

怎么在开发者工具里验证呢?去 Network 面板里看字体请求:如果 Initiator 列显示的是 parser 而不是 preload,或者 Priority 是 Low,甚至状态是 cancelled,那基本可以确定没生效。

字体 preload 的最小可行配置怎么写

其实你不需要写一堆复杂的属性,只要够用就好。下面这个配置是我认为最干净且可靠的写法,专门针对 WOFF2 格式:

对应的 CSS 里,必须有一模一样的 @font-face 规则:

@font-face {  font-family: 'Inter';  font-weight: 700;  src: url('/fonts/inter-bold.woff2') format('woff2');}

这里有几个关键点:

  • 带上 type="font/woff2" 总归是好的,可以避免 MIME 类型探测失败。当然,前提是你的服务器能正确返回 Content-Type: font/woff2。
  • 不要在这个标签上加 onload 或者任何 JavaScript 控制逻辑。字体不需要你手动“激活”,只要 @font-face 注册成功了,浏览器发现页面文字用到这个字体,自己就会去缓存里取。
  • 如果你用了 CDN,那 href 必须写完整的 CDN 域名(比如 https://cdn.example.com/fonts/...),不能只写相对路径,否则跨域问题又得让你头疼半天。

哪些字体不该 preload

千万别犯这个错误:以为预加载就是把所有字重都来一遍的保险操作。事实恰恰相反,预加载是精准狙击,不是地毯式轰炸。你多 preload 一个文件,就多占用一次 TCP 连接,多消耗一次带宽,多挤占其他真正关键资源的优先级。

  • 只预加载首屏立即需要用到的字体组合。比如正文用 font-weight: 400,标题用 font-weight: 700,那你就只 preload 这两个 WOFF2 文件。其他的,等用到时再说。
  • 避免预加载那些可能永远不会在首屏出现的变体,比如 italic、light、thin 等。除非你的设计稿里首屏就用到了。
  • 别给 Google Fonts 那种全家桶式的 family=Inter:wght@100..900 做批量 preload。把它拆解成单个 href,只选你真正会用到的权重。
  • 如果字体 URL 是动态生成的(比如带时间戳或哈希值),必须确保它和 @font-face 里的地址完全一致,不然缓存永远无法命中。

怎么确认字体 preload 真生效了

别光靠感觉,得动手验证。打开 Chrome 的开发者工具,去 Network 面板里看。重点盯住三列:Initiator、Priority、Time。

  • 筛选条件设为 type: font,然后看 Initiator 这一列,找到 preload 字样。如果显示的是 parser 或 script,说明预加载根本没走通。
  • 看 Priority 列,正常情况下应该是 Highest(Chrome)或 High(Firefox)。如果显示的是 Low,那大概率是 as 写错了或者根本没写。
  • 对比一下没加 preload 时这个字体的 Start Time。理想情况下,加了 preload 之后,请求发起的时机应该能提前 200–600 毫秒,尤其是在弱网环境下会更明显。如果时间变化不大,那可能是路径不一致,或者服务端没配 CORS 头(Access-Control-Allow-Origin: *)。
  • 最容易被忽略的一种静默失效:去请求的 Headers 标签页里看 Accept 请求头,是不是 font/woff2?响应头里 Content-Type 是不是也匹配?只要有一个不匹配,预加载的结果就白费了。

还有一个最隐蔽的坑:服务端返回了 302 重定向,或者设置了 Cache-Control: no-store。这样会导致预加载的结果无法被后续渲染复用,而且它不会报错,你只会看到字体反复被下载。这种静默失效往往是最让人头疼的。