2018年如何加载网页字体
自定义网页字体在世界各地广泛使用,但许多(非常非常多)网站加载这些字体的方式不正确,导致页面加载时出现很多问题,例如性能问题、加载时间过长、渲染阻塞以及导航期间字体被切换。
我看到很多开发者忽略了这个论点,或者他们可能一遍又一遍地犯同样的错误,只是因为“他们一直都是这么做的”,也许他们不知道自己是在一个不断变化的环境中工作。
我认为我们应该打破这种恶性循环,从 2018 年开始做正确的事情,因为加载自定义 Web 字体只需要考虑以下四个步骤:
- 请使用正确的字体格式
- 预加载字体
- 正确的字体声明
- 避免字体加载期间出现不可见文本
让我们逐一分析这些要点。
请使用正确的字体格式
网页上可以使用多种字体格式,但如果您不需要支持 IE 8 或更低版本(什么鬼?!),那么真正需要的只有两种格式:woff和woff2。您应该只使用这两种文件类型,因为它们默认经过 gzip 压缩(因此文件非常小),并且针对网页进行了优化。正如您所见,IE 9 及更高版本以及所有其他主流浏览器都完全支持它们。
预加载字体
rel使用自定义字体时,应使用相应的标签和属性告诉浏览器预加载它们:
<link rel="preload" as="font" href="fonts/cicle_fina-webfont.woff2" type="font/woff2" crossorigin="anonymous">
<link rel="preload" as="font" href="fonts/zantroke-webfont.woff2" type="font/woff2" crossorigin="anonymous">
请注意,这里使用了 crossorigin 属性
important;如果没有此属性,浏览器会忽略预加载的字体,并重新获取字体。这是因为浏览器需要匿名获取字体,而预加载请求只有通过使用 this 属性才能实现匿名化。
在上面的例子中,这些rel="preload" as="font"属性会要求浏览器尽快开始下载所需的资源。它们还会告诉浏览器这是一个字体,以便浏览器能够正确地在资源队列中对其进行优先级排序。使用预加载提示将显著提升网页字体的性能和页面初始加载速度。支持预加载和预取提示的浏览器一旦在 HTML 文件中检测到提示,就会立即开始下载网页字体,而无需再等待 CSS 加载完成。
你可以使用该rel="prefetch"属性告诉浏览器,在页面加载或用户操作期间,稍后再下载可能需要的资源,这样浏览器就会为该资源分配较低的优先级。
注意:
如果您使用像 Google Fonts 这样的 CDN,请确保预加载的字体文件与 CSS 中的字体文件匹配。字体会定期更新,如果您预加载的是旧版本字体,而 CSS 中却使用了新版本字体,则可能会下载同一字体的两个版本,从而浪费用户的带宽。为了便于维护,建议您考虑使用<link rel="preconnect">👨🏼🔬等其他方式。
正确的字体声明
声明字体系列非常简单,但我们需要注意一些事项。以下是一个声明自定义字体系列的正确示例:
@font-face {
font-family: 'Custom Font';
font-weight: 400;
font-style: normal;
font-display: swap; /* Read next point */
unicode-range: U+000-5FF; /* Download only latin glyphs */
src: local('Custom Font'),
url('/fonts/custom-font.woff2') format('woff2'),
url('/fonts/custom-font.woff') format('woff');
}
Google Web 基础知识中的 Unicode 范围
如您所见,我们仅使用优化后的字体(woff和woff2),并指示浏览器仅下载所需的字形范围(从U+000到U+5FF)。还有两点需要注意:local()函数和字体顺序。第一个函数允许用户使用本地字体副本(例如,Android 系统预装的 Roboto 字体),而无需下载。字体声明顺序也很重要,因为浏览器会按照声明顺序开始获取资源。如果浏览器支持 woff2 格式,则会下载该字体;如果浏览器无法识别资源格式,则会继续获取下一个,依此类推。如果您确实想同时使用eot和ttf字体,请确保将它们添加到声明的末尾src。
资源
- Eli Fitch 的字形范围生成器
unicode-range- 现代字体生成器
避免字体加载期间出现不可见文本
字体文件通常很大,即使经过 gzip 压缩也需要一段时间才能加载。为了解决这个问题,一些浏览器会在字体加载完成前隐藏文本(即“文本闪烁”)。你可以使用系统字体来避免这种“闪烁”,让用户立即看到内容,然后再替换成字体。
在前面的@font-face示例中,您可以注意到font-display声明。该swap值告诉浏览器,使用此字体显示的文本应立即使用系统字体。自定义字体准备就绪后,系统字体将被替换。
如果浏览器不支持 font-display该字体,则会继续沿用其默认的字体加载方式。
| 浏览器 | 字体未准备就绪时的默认行为…… |
|---|---|
![]() |
使用系统字体,直到字体准备就绪。然后更换字体。 |
![]() |
将隐藏文本最多 3 秒。如果文本尚未准备就绪,则使用系统字体,直到字体准备就绪。切换字体。 |
![]() |
将隐藏文本最多 3 秒。如果文本尚未准备就绪,则使用系统字体,直到字体准备就绪。切换字体。 |
![]() |
字体加载完毕前,文本将被隐藏。 |
测试
以下是测试“标准版”和优化版的链接:






