在大多数网站上,Web 字体仍然是最容易获得的性能收益
距离 variable fonts 推出已有五年,距离 WOFF2 普及已有十年,但普通网站加载字体的方式仍然不对。下面是把它做对的简明版本。
反复出现的模式
如果你今天随机审计十个生产网站,会发现其中大多数的字体状况大致相同:
- 首页加载了六到十个字体文件
- 它们全都是 WOFF2(好),但没有
font-display策略(不好) - 有几个字重和样式在页面任何地方都没有用到
- 整套字体栈都由第三方域名提供(通常是 Google Fonts),随之带来 DNS、TLS 和隐私成本
- 没有
unicode-range子集化,因此即使页面是英文,每位访问者也会下载西里尔和希腊字形
这并不是小网站独有的问题。许多资金充足的营销页面,仍然会在第一段文字可绘制之前加载 600 KB 的字体。一旦你开始注意到这种模式,就很难再忽视它。
修复方法并不稀奇。它只是一些浏览器多年来一直支持、已经被充分理解的技术。
用一个 variable font 代替六个静态字体
如果你正在加载 Inter Regular、Inter Medium、Inter SemiBold、Inter Bold 以及 它们的斜体,那么你下载的字节数大约是实际需要的六倍。一个 Inter variable font 可以用一个文件覆盖整个字重轴(在某些构建中也包括倾斜轴),而这个文件只比两个静态字重略大。
浏览器支持的问题多年前就已经解决了——variable fonts 在所有重要的浏览器中都可用。剩下的迟疑,大多只是静态字体时代留下的肌肉记忆。
一个实用的经验法则:每种文字、每个字体族使用一个 variable font 文件。拉丁文字一个文件,西里尔文字另一个,希腊文字第三个,并用 unicode-range 条件加载。就这么简单。
设置合理的 font-display
当自定义字体仍在加载时,默认行为是显示什么都没有——也就是不可见文本——最长可达三秒。这是最糟糕的默认值。用户看到空白页面,会以为哪里坏了。
把下面这段加到每个 @font-face 规则中:
@font-face {
font-family: 'Inter';
src: url('/fonts/inter-var.woff2') format('woff2-variations');
font-weight: 100 900;
font-display: swap;
}
swap 会立即显示 fallback 字体,并在自定义字体加载完成后替换进去。用户从第零毫秒就能阅读页面。代价是替换发生时会有一次短暂的布局偏移,而你可以用下一项技术来缓解它。
匹配 fallback 指标
只有当 fallback 字体和自定义字体的指标差异很大时,无样式文本闪烁才会显得刺眼。现代 CSS 用 size-adjust、ascent-override 以及相关属性解决了这个问题:
@font-face {
font-family: 'Inter Fallback';
src: local('Arial');
size-adjust: 107%;
ascent-override: 90%;
descent-override: 22%;
line-gap-override: 0%;
}
调整好 fallback 指标后,替换几乎难以察觉——自定义字体到达前后,文字占据的水平空间保持一致。
Google 的 --allow-fallback-font-metrics 工作现在已经成为浏览器基线支持,并且已有工具链(fontaine 库及类似工具)可以在几秒内为你计算出正确数值。
自托管
Google Fonts 很方便、免费,但也带来两个真实成本:
- 第二次 TLS 握手。 即使有 HTTP/3 和连接合并,额外的 origin 也很少是免费的。
- 隐私和合规问题。 多个欧洲法院已经裁定,从
fonts.gstatic.com加载 Google Fonts 构成向第三方传输个人数据(IP 地址)。自托管可以彻底消除这个问题。
下载并托管的流程是:
- 获取 WOFF2 文件(如果存在 variable build,就用它)
- 将它子集化到你的受众实际使用的文字
- 从与网站其余部分相同的 origin 提供它,并设置较长的
Cache-Control: max-age=31536000, immutable - 预加载最关键的字重:
<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-var.woff2" crossorigin>
这就是完整流程。对现有网站来说,它需要一个下午,而且你几乎不会再回头。
什么时候完全跳过自定义字体
有必要直接说清楚:并不是每个网站都需要自定义字体。系统字体栈现在在每个操作系统上都确实很漂亮:
font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Inter, sans-serif;
字重是对的,指标是对的,渲染针对设备做了调优,线上传输的字节成本恰好是零。对于工具类网站、内部应用、优先考虑内容的作品集,或任何面向慢速网络用户的产品,系统字体栈就是正确答案。
<!-- tool-cta:start -->
💡 试试这个: 使用 Webfont Generator 将你的 TTF 或 OTF 文件转换为带有即用型 CSS 的现代 WOFF2,这正是文章推荐的格式转换。
<!-- tool-cta:end -->
坦率总结
对于一个典型的小型网站,四个步骤就覆盖了整个 Web 字体性能问题:
- 每个字体族、每种文字使用一个 variable font
- 使用
font-display: swap,并配合匹配的 fallback 指标 - 自托管,设置较长的缓存头,并为关键字重添加
preload - 或者完全跳过字体,使用系统字体栈
做一次这些工作,你就能从首页收回数百 KB,获得几百毫秒的感知性能提升,并顺手移除一个第三方依赖。很少有改动能有这么高的投入产出比。


