使用自定义字体提高性能的三种技巧

Avatar of Ollie Williams
Ollie Williams

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

在网页字体领域有很多好消息!

  1. 即将推出的 Microsoft Edge 版本将 最终实现 unicode-range,它是最后一个实现此功能的现代浏览器。
  2. 预加载和 font-display 将在 Safari 和 Firefox 中推出。
  3. 可变字体 正在全面推广。

以高性能的方式使用自定义字体变得越来越容易。让我们来看看在使用自定义字体时可以做些什么,以确保我们尽可能地提高性能。

1) 减少文件大小

许多字体不仅包含数字,还包含拉丁字母和常用标点符号,它们支持多种语言并包含数千个额外的字形,这会大大增加文件大小。

Mac 工具 Font Book 可以显示字体中所有可用的字形。

在这些情况下,子集化非常有用。子集化是指删除不需要的字符。您可以使用命令行工具pyftsubset执行此操作,该工具可以作为 FontTools 的一部分下载。(网站 FontSquirrel 提供了子集化的 GUI。它是一个流行的替代方案,也值得考虑 - 但请注意它与可变字体不兼容)。指定要保留的字符的最简单方法是使用 Unicode。Unicode 是一种标准,它为来自世界各地语言的每个字符提供唯一的代码。

Unicode 已为数千个字符分配了数字。我们只对非常有限的子集感兴趣。

pyftsubset 命令后面跟着您的字体文件名称和指定您选择的 Unicode 范围的 Unicode。以下子集适用于英语。

pyftsubset SourceSansPro.ttf --unicodes="U+0020-007F"

然后,您可以通过压缩到 woff2 文件格式 来进一步减小字体的大小。您可以使用 Google 的独立命令行实用程序 执行此操作,或者在运行pyftsubset 命令时添加一些额外的选项

pyftsubset SourceSansPro.ttf --unicodes="U+0020-007F" --flavor="woff2" --output-file="SourceSansPro.woff2"

如果您确信不会使用从字体中删除的任何字符,那么您只需要执行这些操作即可 - 您已大幅降低了字体的大小,现在可以像往常一样在 @font-face 中使用它。但如果网站上的某些页面使用了从字体中删除的额外字形怎么办?您需要避免任何字符以 备用字体 显示。为了解决此潜在问题,请务必记下使用pyftsubset 创建子集时使用的范围。您需要在@font-face 块中指定它。

@font-face {
  font-family: 'Source Sans Pro';
  src: url('/fonts/SourceSansPro.woff2') format('woff2');
  unicode-range: U+0020-007F; /* The bare minimum for the English Language */
}

上面的unicode-range 指定了可能在网站的所有页面上使用的字符。因此,此字体将在每个页面上下载。

Firefox 拥有最好的与字体相关的开发工具。查看 Firefox 中的“字体”选项卡,以了解正在使用的字体。在其他浏览器中,查看“网络”选项卡,以了解正在下载的字体文件。

我还将使用pyftsubset 创建另一个文件。此文件不会重复第一个文件中的任何字符。相反,它将包含网站上很少使用的字形。

pyftsubset SourceSansPro.ttf --unicodes="U+00A0-00FF,U+0100-017F" --output-file="SourceSansProExtra.ttf"

通过再次在另一个@font-face 声明中指定unicode-range,我们确保该文件只在需要时下载 - 当页面上的字符与指定范围匹配时。

@font-face {
  font-family: 'Source Sans Pro';
  src: url('/fonts/SourceSansProExtra.woff2') format('woff2');
  unicode-range: U+00A0-00FF, U+0100-017F; /* additional glyphs */
}
在 HTML 中添加一些随机的法语重音符号将导致额外子集文件被下载。

您应该根据自己的目的调整范围。如果标题或页脚中包含任何不寻常的标点符号或字母,请确保将它们包含在主字体文件中,否则两个文件将始终被下载。例如,对于我工作的网站,我在主子集中包含了 © 符号(U+00A),因为它包含在每个页面的底部。您可以在 维基百科上找到一个方便的 Unicode 字符列表

2) 尽早加载关键字体文件

想象一下,您样式表中唯一的 CSS 是 100 个@font-face 声明和以下代码行

* {
  font-family: 'Lora';
  font-style: italic;
  font-weight: bold;
}

浏览器会下载多少字体?100 个?答案是
只有一个。字体默认情况下是延迟加载的。这是浏览器供应商的明智之举 - 只下载实际需要的内容。但是,也存在一个缺点。为了知道正在使用哪些字体变体,浏览器必须解析所有 HTML所有 CSS。只有完成所有这些操作后,才会请求任何字体文件。如果我们想更快地启动操作,就必须使用预加载

预加载就像在文档的头部添加一个链接标签一样简单

<link rel="preload" href="/fonts/Lora-Regular.woff2" as="font" type="font/woff2" crossorigin>
预加载的字体是 HTML 文档本身之后下载的第一个资源。

预加载太多资源或者浪费地预加载页面可能不会使用的任何资源都不好。出于这个原因,我只坚持预加载普通权重、非斜体文件。我并不太担心延迟加载粗体或斜体文件,因为这些样式在整个网站中使用频率较低。这些字体文件的未样式文本闪烁 (FOUT) 不如常规罗马字体的 FOUT 那么令人反感,因为常规罗马字体构成了大部分文本。如果您使用的是可变字体,则不会出现此问题。但是,目前预加载可变字体会带来自己的问题。

是否应该预加载可变字体?

向浏览器发送它无法使用的资源显然是浪费的。这就是为什么我们在其中包含一个type 属性,用于指定资源的 MIME 类型。如果浏览器不支持该资源,它将不会被下载。在字体的情况下,我们指定type="font/woff2"。Edge、Safari 和 Firefox 正在同时实现可变字体和预加载,因此对于这些浏览器来说不存在问题。但是,Chrome 和 Opera 从 2016 年开始就支持预加载。可变字体是全新添加的功能,而 woff2 从 2014 年开始就已支持。因此,预加载可变 woff2 将迫使旧版本的 Chrome 和 Opera 下载它们不知道如何处理的资源。

理想情况下,我们应该能够 在 type 属性中将资源指定为可变字体,但这在很大程度上是不必要的。Chrome 是常青的。每六周就会发布一个新版本,并且会在后台自动更新。使用旧版本的用户相对较少。一旦可变字体在 Chrome 中存在了几个版本,就可以安全地预加载。

3) 管理 FOUT 和 FOIT

到目前为止,我们已经研究了如何加快字体加载速度。良好的用户体验不仅仅与页面或字体的总加载时间有关 - 还在于用户在加载过程中如何体验网站。如果您希望用户留下来,就需要考虑感知性能。不同的浏览器在管理字体加载方面并不一致。现在,我们可以使用 CSSfont-display 属性轻松地为我们自己决定加载策略。

font-display 属性在@font-face 块中定义。

@font-face {
  font-family: ExampleFont;
  src: url(/fonts/SourceSansPro.woff2) format('woff2');
  font-display: fallback;
}

可用的选项有blockoptionalswapfallback。您应该选择哪一个?

optional 值听起来很不错——字体是锦上添花的功能,并非必要条件。但在实际操作中,我发现它并不理想。用户在导航或刷新页面时看到页面字体发生变化是意料之外的,而且有点令人不安。自定义字体加载的时间窗口非常小。如果你预加载了字体,它很可能在这个狭窄的时间范围内加载完成。如果没有,用户往往会看到备用安全字体——即使是在高性能电脑上,网络连接良好时也是如此。这对品牌一致性来说不太好。如果你花了很多时间寻找类似的备用字体,这可能是一个可接受的选项,但如果它们非常相似,而且性能至关重要,那么你可能需要重新考虑为什么要使用自定义字体。

swap 值是更好的选择。安全字体立即显示,并在自定义字体加载后被替换。不幸的是,替换时间是无限的,所以在连接速度慢的情况下,字体可能会在用户已经沉浸在文本中的时候发生变化,从而造成一种突兀和令人不安的体验。

fallback 值与大多数浏览器的默认行为类似——短暂的不可见文本阻塞,如果自定义字体仍然没有加载,则显示备用字体。与 swap 不同,它有一个超时时间。如果自定义字体在三秒内没有加载,字体就不会改变——用户只能看到备用字体。你可以阅读 CSS-Tricks 上的一篇完整文章 关于 font-display 的内容,并决定哪种选项最适合你。

总结

文本在大多数网站内容中占据很大比例。因此,字体加载是性能拼图中的重要一环。如果你想了解字体加载的最新发展,Zach Leatherman 刚刚开始了一个关于这个主题的 时事通讯