自托管字体(self hosted fonts):把网页字体搬到自己的服务器上
self hosted fonts 是把网页字体文件放在自己域名下、不走 Google Fonts 这类第三方。这篇讲清你搬走了哪一段请求链、@font-face 与 preload 两段可粘代码,以及一个能防止字体切换顶动布局的兜底做法。

自托管字体(self hosted fonts)指的是把网页字体文件放在自己的域名下,而不是走 Google Fonts 这类第三方。它值不值得做,只看一件具体的事:少一个域名要解析。浏览器打开页面的那条连接连的是你自己的服务器,字体放在同一个域名,DNS 和 TLS 都能复用;放在别人家,就得先连过去、下一个样式表、读出里面的 @font-face,才知道字体文件在哪。代价是子集化、缓存和授权这三件事得自己扛。
先读这篇
你需要能往站点里加文件、能改 HTML 或 CSS。不需要构建工具。这篇默认你知道为什么文档头部很贵;不清楚的话先看 render blocking resources。这条改动最终喂给的是 largest contentful paint;真实网站到底怎么放字体,数字在 26 个首页的字体实测里,和本篇是方法与数字的两半。
为什么 self hosted fonts 改变关键路径
链到 Google Fonts 花的请求不止一个。浏览器先连 fonts.googleapis.com 拉一个样式表,解析出里面的 @font-face,再去连 fonts.gstatic.com 拿真正的字体文件。两个域名、两次 DNS、两次 TLS,还是一条链:样式表没到、没解析完,字体文件根本不会开始下。把文件搬到自己域名,新增域名数就是零。
原因是你的页面本来就连着自己的域名。HTML 从这里来,DNS 答案在缓存里,TLS 会话是开着的。同源的字体把这两样都复用掉;第三方的字体复用不了,而且浏览器在下载并解析完别人家的 CSS 之前,压根不知道有这个字体。
自托管字体,是浏览器画第一笔之前要信的域名少了一个。
自托管到底省下什么
省的不是字节。字体文件不管你发还是 Google 发都一样大,Google 的 CDN 也很快。省的是往返次数和依赖关系。下面这张表是「画第一个字形之前」的请求链。
| 环节 | Google Fonts | 自托管 |
|---|---|---|
| 新解析域名 | 2 个 | 0 个 |
| 新 TLS 握手 | 2 次 | 0 次 |
| 字体文件之前 | 1 个样式表 | 0 个 |
| 谁能改谁能挡 | 第三方 | 你自己 |
这张表带出两件事。第一,首屏不再等一个别人家的样式表。第二,你不再把每个访客的 IP 都交给那家公司——隐私评估里被反复问到的正是这一条。两件事单独都不构成排名因素;它们改变的是冷连接下页面的手感,而指标最差的时候通常就是冷连接。
按这个顺序做
六步,每一步都有一个可查的完成标志。第一步别跳,它决定你会不会踩授权。
- 逐个确认字体的授权。Google Fonts 家族按开源许可发布(含 SIL OFL 与 Apache 2.0),允许再分发;foundry 字体和付费字体往往不允许,网页字体授权通常按访问量计价。完成标志:每个文件都能指到它的许可。
- 下 woff2 文件。从字体自己的站点、Fontsource 这类包、或提供方的下载页拿。完成标志:文件在本地,按家族与字重命名。
- 裁到你会用到的字符集。一套完整的中文字体动辄几 MB,拉丁子集常在 30 KB 以内。完成标志:文件小到你能报出它的体积。
- 放到自己的域名下。任何你能控制的路径都行,包括在自家主机前面挂 CDN。关键在 origin,不在那块盘。完成标志:直接请求这个文件从你的域名返回 200。
- 写 @font-face,并预加载首屏要用的那一个文件。两段都在下面的交付物里。完成标志:网络面板显示字体从你的域名到达,并且没有发往 fonts.googleapis.com 的请求。
- 删掉旧的 link。移除 Google Fonts 的样式表链接,以及指向它的 preconnect。完成标志:全新加载对第三方域名的请求为 0。
交付物:两段可以直接粘
self hosted fonts 的全部落地动作就是下面两段。第一段是字体本身的规则。unicode-range 那行可选,但它能让浏览器不去下永远用不到的范围。font-display 决定文件还在路上时怎么办,对读者正在读的正文来说 swap 是安全的默认值。
@font-face {
font-family: "Inter";
src: url("/fonts/inter-latin.woff2") format("woff2");
font-weight: 100 900;
font-style: normal;
font-display: swap;
unicode-range: U+0000-00FF, U+0131, U+2000-206F;
}
第二段放进头部,让浏览器在解析到引用它的样式表之前就开始下字体。字体的 preload 必须带 crossorigin,即使同源也一样——字体是按 CORS 模式抓取的。
<link rel="preload" href="/fonts/inter-latin.woff2" as="font"
type="font/woff2" crossorigin>
预加载只有在那个字体首屏要用时才划算。全预加载等于让浏览器跟自己抢带宽,用下面这张表来决定。没进表的照样会加载,只是晚一点。
| 字体角色 | 预加载 | 原因 |
|---|---|---|
| 首屏标题字体 | 要 | 首屏就要画,晚到就是肉眼可见 |
| 正文字体 | 不要 | 文件没到时兜底字体够用一会 |
| 同家族第二个字重 | 不要 | 首屏通常只用一个字重 |
| 图标或装饰字体 | 不要 | 很少进首屏,有时根本不用 |
做错了会怎样
三种失败反复出现。它们都不报错,所以值得点名。
- 搬了文件却没配兜底字体。没有度量接近的兜底字体,从兜底切到你的字体会把文字顶动,表现出来就是布局偏移。挑一个字宽接近的系统字体,能设 size-adjust 就设。
- 发了没裁的字体。一套完整中文字体常在 3 MB 以上。为了省两个往返去下一个这么大的文件,在手机上是很差的交换。先裁,再测。
- 删了 link 却留着 preload。没有对应 @font-face 的 preload 是一次白下的请求,浏览器还会打警告。两段要同步。
常见问题
自托管字体对 SEO 更好吗?
本身不会。没有任何字段奖励字体文件的来源。只有当它减掉了关键路径上的工作、或修掉了一次布局偏移,才会有帮助,而这两件事喂的是页面体验信号。把它当性能修复,不要当排名技巧。
google fonts 怎么自托管?
把要用的家族与字重的 woff2 下下来,脚本大就先裁子集,放到自己域名,加上上面那段 @font-face,预加载首屏要用的那一个文件,然后删掉 Google Fonts 的 link 和它的 preconnect。验收标准是全新加载时对 Google 字体域名的请求为 0。
自托管字体会改善 Core Web Vitals 吗?
能推动数字,但没有固定目标值。移掉一个阻塞样式表可能把 largest contentful paint 提前,好的兜底字体让累积布局偏移更小。提升多少取决于你原来的设置、连接和缓存,所以要改前改后各测一次,而不是想当然。
自托管网页字体合法吗?
取决于每一个字体自己的许可,跟你从哪儿下到的无关。开源字体许可(OFL、Apache 2.0)通常允许再分发;商业字体往往不允许,少数只允许按访问量的方案。这一步我们不做简化:每一个文件都读一遍许可。
自托管会不会把站点改坏?
会,在三个地方。CSS 引用了你没定义的字体名,文字会静默回退;删掉一个其实在用的字重,浏览器会伪粗或伪斜,字看着变形;在新文件上线之前就删了第三方,中间那段时间所有访客都会闪一下无样式字体。
边界说清楚:这篇讲的是文件从哪儿来,不是选哪款字体。我们没有测过自托管的排名影响,也没有一个固定的省下多少毫秒的数字,因为它取决于你现有的缓存、CDN 和冷启动。在很快的 CDN 加命中缓存的情况下,差别可能不到一百毫秒、几乎看不出来。能一直成立的是「少一个第三方域名」这件事。把它当成 QueryWin 处理渲染这条链里的一环是合理的,但授权检查要放在最前面。
本文属于 QueryWin 实操手册 · 第 2 阶


