字体性能及用户体验探索

网页字体的加载使用频繁且广泛,之前一直没有对这些字体进行过深入的探索,经过资料的查询和研究分析,网站字体的设置建议同时满足以下 7 个条件:

1. 使用 Webfont 字体 (.woff2 格式)

选择 Google font 的字体进行网页的设计,因为它属于开源的,可以免费商用,无需过多地担心版权问题,并且更重要的是,Google 字体均提供 Webfont 格式。

Webfont 是基于 TTF & OTF 等字体格式的封装和优化压缩,所以体积更小,加载速度更快,对于设备浏览器的兼容性更好,它的字体格式为 .woff2 和 .woff

WOFF (Web Open Font Format) 是专为 Web 开发而设计的字体格式。woff2 是 woff 的下一个版本,比 woff 有更好的压缩效果,速度更快,但兼容性方面目前还在推进中,所以它的兼容性没有 woff 好。

这里建议直接使用 woff2 一种格式即可,如果字体没有提供 woff2,则使用 woff,不必为了效果和兼容性加载多个格式文件,使用这种格式基本已经覆盖了网站大部分类型的用户,即超过 80% 的用户,剩下的 20% 使用其他的兼容性措施弥补即可。

CSS 的加载方式如下所示:

@font-face {
  font-family: MyWebfont;
  src: url('font/MyWebfont.woff2') format('woff2');
}

2. 将字体托管在自己的服务器上并设置缓存

网上很多人都提到不要直接使用 Google 字体加载,它会影响网页加载性能。

1) 如果直接加载 Google 字体,则网页会向两个外部域发出请求:

  • fonts.googleapis.com 这个域用于加载样式表
  • fonts.gstatic.com 这个域用于加载字体文件

你是否了解过自己的网站所依赖的外部域数量有多少?如果在 5 个以内,则不用太担心,如果过多,它可能会致使你的网页加载变慢。如果将文件托管在自己的服务器上则可以避免前面两个域的连接请求。

2) 加载 Google 服务器上的字体,缓存时间非常短!只缓存 1 天的时间。我们通过 F12 > Network > Ctrl + F5 刷新页面即可查看文件的缓存时间,见下图:

网站在设计完成后,字体修改的可能性极低,我目前为止没有见过哪个网站会经常更换字体的,我们可以将字体托管到自己的服务器上,以便更好地控制缓存设置,然后设置缓存时间为半年甚至一年。如果你不设置缓存,或设置极短的缓存时间,那么当你使用 PageSpeed 测试页面速度的时候,它会建议你延长字体的缓存时间。

3) 如下图所示,Google 加载的字体样式表是没有经过任何压缩的,并且它会加载非常多字体文件以便达到最优的兼容性。

但实际上这些加载非常冗余,我们知道,英文属于拉丁字母,有些 Google 字体在设计之初就支持多种文字系统 (e.g. 希腊字母……),Google 提供的样式表会将这些字母系统也全部加载出来,在网页运用上很多时候都没有必要,我们可以用其他方式去弥补兼容性方面的不足。

优先选择使用 Google webfonts helper 去下载你想要的字体,因为这里面下载的字体会区分出这些字母系统,帮助你剥离多余的加载。

3. 只使用一款自定义字体及少量的字体样式

自定义字体的加载往往会对网页性能造成影响,原因是在字体加载前,需要先从服务器上将字体下载下来,然后浏览器拿着下载下来的字体进行页面的渲染。

如果出于设计效果的需要,整站只建议有且只有一款自定义字体。每多一个字体加载,都会对页面加载速度造成一次冲击。比如,你在网站上同时加载了 Open Sans 和 Roboto 这两款字体,这种设置没有什么意义,不仅影响页面加载性能,同时还破坏网站字体的规范统一。

这里指的一款字体,不包含字体的不同样式,如粗体、斜体等。一般情况下,我们只建议加载两种样式,一种是常规的基础字体 (即正文字体),一种是加粗的字体 (即标题) 即可。鉴于用户体验和设计效果的平衡取舍,没有太大的必要加载多个样式字体。

目前字体 font-weight 根据粗细程度分别有以下几种,但大部分字体都只有其中的几种粗细形式:

  • 100 – Thin
  • 200 – Extra Light
  • 300 – Light
  • 400 – Regular
  • 500 – Medium
  • 600 – Semi Bold
  • 700 – Bold
  • 800 – Extra Bold
  • 900 – Black

为了记忆和使用的简便性,一般使用数字表示,且数字比起单词字节数更少。如果你仔细观察,你会发现 Google font 提供的 <link> 加载方法,以及 Google webfonts helper 页面提供的字体加载方法,均使用的数字表示,而不是 Light, Bold …

很多时候,采用哪种方法的背后都有一些因素的考虑,如果不明白为什么且没有太多的思考研究时间,那么,沿用大厂在用的形式基本没有太大问题,大的品牌站点经历过更多的大风大浪,要考虑的方面也会更多。

CSS 的设置如下:

@font-face {
  font-family: MyWebFont;
  src: url('font/MyWebfont-Regular.woff2') format('woff2');
  font-weight: 400;
}
@font-face {
  font-family: MyWebfont;
  src: url('font/MyWebfont-Bold.woff2') format('woff2');
  font-weight: 700;
}

4. 设置 preload 预加载

鉴于加载速度的最佳化,设置资源加载的优先级,将减少 FOIT (Flash of Invisible Text) 时间。因为字体是页面加载的基础资源,所以使用自定义字体时,应告知浏览器资源加载的优先级,使用相应的 rel="preload" 来预加载你最重要的资源 (不要滥用),比如 image, CSS, jQuery, font 文件,使用这个属性,需同步配合使用 as 或者 type ,浏览器会根据你设置的资源类型来判断哪个资源优先级更高,preload 使用 as="style" 样式属性将获得加载的最高优先级。

使用方法是在 </head> 前面添加 preload 属性,代码如下所示:

<link rel="preload" href="font/MyWebFont.woff2" as="font" crossorigin>

除了 preload 外,还有 preconnect 通常用于与第三方的服务器提前建立连接。如果是直接引用的 Google 字体, 那么意味着你的网页需要从它们的服务器下载文件,所以,你会看到 Google 字体官网给出的加载方法里面,添加了额外的一个 preconnect 属性,这是基于加载速度考虑的,它提供的 <link> 如下所示:

<link rel="preconnect" href="https://fonts.gstatic.com">

5. 使用无衬线字体 (sans-serif) 更易于阅读

在当前主流的一些设备浏览器中,无衬线字体比衬线字体更易于阅读,在我留意过的所有大型网站 (e.g. Google, YouTube, Apple, Microsoft…) 均会默认整站为无衬线字体,即使用 sans-serif 属性。

CSS 的写法如下所示:

font-family: sans-serif;

6. 使用 swap 优先显示本地默认字体

我们知道,要显示出自定义的字体,需要先从服务器下载下来,然后浏览器进行页面的渲染,这个期间,如果不添加 swap 的属性,页面加载时将明显感知到有几秒空白时间,然后字体一下蹦出来,在网络不好的情况下,页面空白将持续更长时间,极度影响用户体验。

如何设置 swap 属性,CSS 的写法如下:

font-display: swap;

如果是以 link 的方式添加在 </head>,那么则在链接最后加上 &display=swap

<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap" rel="stylesheet">

7. 使用系统字体做为备选

我们都知道,font-family 通常都会指定几种字体,原因是其他字体都属于备选项,当网页无法成功加载第一个字体时,那么会顺延到第二个字体的加载。

那么我们该如何选择备选字体呢,是否随意指定一款字体都能做为备选?当然不是,我们设置它是有原因的,是为了解决兼容性的问题,同时,字体的阅读体验还不能产生太大影响。

使用系统字体的好处在于网页可直接调取用户电脑本地字体,这大大减少很多网页加载时间和渲染阻塞,且兼容性往往很好。

运用系统字体的方法非常简单,直接在 CSS 上调取下面的参数即可。

  • system-ui 使用用户当前系统的默认字体
  • -apple-system 是 system-ui 的兼容性写法,仅作用 macOS 和 iOS 系统
  • BlinkMacSystemFont 也是 system-ui 的兼容性写法,仅作用 macOS 系统

注意:此方式仅作用在 font-family 上,而使用简写 font 引用并不生效。

CSS 的写法如下:

font-family: system-ui, -apple-system, BlinkMacSystemFont;

system-ui 是后来推出的,目前已兼容当前主流浏览器,且被越来越多的网站运用。同时,用户也可自行更改自己系统的默认字体 (用户自己更喜欢、感觉更舒适的字体),用户选择的字体可能有些情况下是不兼容且不可控的。所以,我们除了这个设置外,依然需要再挑选一款字体作为备用。

想必大家都不陌生的 Arial 字体,它是从 Windows 3.1 版本开始就装机默认必带的字体之一,这意味着它兼容目前市面上所有的 Windows 系统版本,同时它支持多种字母系统,所以在一开始,它也被各大网站广泛运用于备选字体上。

其他更多可用作备选字体的,可以通过维基查询 Windows 目前的装机字体大概是在什么系统开始支持的。

List of typefaces included with Microsoft Windows

然后根据你主要的用户群体所在的系统版本设备去挑选备用字体,比如主流的安卓手机默认的装机字体为 Roboto,这里不做展开,这些备用字体全部都在用户自己使用的设备上 (本地),所以对页面加载性能没有什么影响。


网站字体加载最佳实践方式

综上所示,了解了这些情况后,就是整体融合并运用的问题,下面将用 Open Sans 字体举例说明:

1)Google webfonts helper 搜索 Open Sans 并将字体下载下来,只选择拉丁字母,根据你的网页设计选择两种字体粗细,一般为常规字体和加粗字体即可,选择完成后,点击底部的 open-sans-v18-latin.zip 按钮进行下载。

注意:下载下来的字体只选择 .woff2 格式的两个字体 (常规 & 加粗) 文件放到你的服务器相应路径下即可,字体文件可自行重命名。

2) 设置预加载,在 </head> 前添加如下代码,herf 里面的字体链接依据你托管的字体路径进行填写:

  • 如果使用的是 WordPress 系统,则前面需添加路径函数,一定不要写死域名链接 (便于兼容多个不同的测试环境,同时还能避免一些失误),让其自动获取。
<link rel="preload" href="<?php echo get_template_directory_uri() .'/fonts/OpenSans-400.woff2'; ?>" as="font" crossorigin>
<link rel="preload" href="<?php echo get_template_directory_uri() .'/fonts/OpenSans-700.woff2'; ?>" as="font" crossorigin>
  • 如果使用的是 cdn 域名托管,则直接指定 cdn 的路径
<link rel="preload" href="https://your_cdn_domain_name.com/fonts/OpenSans-400.woff2" as="font" crossorigin>
<link rel="preload" href="https://your_cdn_domain_name.com/fonts/OpenSans-700.woff2" as="font" crossorigin>

3) 设置预加载后,在 CSS 里加载字体样式。

据我所知,如果字体名称包含空格,则需要添加一个双引号 “ ” 或单引号 ‘ ’,但你会发现实际上哪一种都有人在使用,无论是 Arial, ‘Arial’, “Arial” 都是等效的,仅 CSS3 定义的通用字体系列 (如 sans-serif) 必须写成无引号。

W3C 提到,为了避免转译的错误,用引号引用除连字符 (-) 以外的包含空格数字标点符号的字体系列名称。

To avoid mistakes in escaping, it is recommended to quote font family names that contain white space, digits, or punctuation characters other than hyphens

CSS Fonts Module Level 3

字体样式 CSS 写法如下:

@font-face{
	font-family:'Open Sans';
	src:url('fonts/work-sans-400.woff2') format('woff2');
	font-weight:400;
	font-display:swap;
}
@font-face{
	font-family:'Open Sans';
	src:url('fonts/work-sans-700.woff2') format('woff2');
	font-weight:700;
	font-display:swap;
}

4) CSS 全局渲染运用这些字体,后续只需使用设置好的 font-weight 去调用这两种字体的粗细即可。

body {font-family:'Open Sans',system-ui,-apple-system,BlinkMacSystemFont,Arial,sans-serif;}

如果你希望网页支持表情,则需在 sans-serif 后面添加如下字体系列名称

  • Apple Color Emoji
  • Segoe UI Emoji
  • Segoe UI Symbol

网站的设计趋势和技术都是不断进化的,未来依然需要根据情况进行修改以适应新的趋势和需求。