这篇文章的作者(我们今天将要翻译的译本)想谈一谈为什么他即使不应该预加载字体也为什么要预加载字体。

当他创建一个网站时,他将该材料的
原始版本发布在该网站上,但他不会在该网站上使用任何自己的字体。 尽管影响不大,但这将不可避免地影响站点性能。 文章的作者说,他努力建立一个快速的网站。 但是,最终决定对页面标题使用一种特殊的字体,同时尝试使此解决方案对项目性能的影响尽可能小。
开始使用
首先,我决定使字体文件尽可能小。 所以我创建了这种字体的一个子集。 换句话说,我仅从字体中选择了标题中单词所必需的那些字符。
结果,我得到了一个非常紧凑的文件,其大小小于2 Kb。 此外,我将其与网站上所有其他材料放置在同一位置,这使我摆脱了第三方依赖关系以及连接到另一个域所花费的时间。
最后,字体文件的链接放置在页面中嵌入的CSS代码中,HTML代码的顶部,而不是外部CSS文件中。
这意味着浏览器可以检测并下载字体文件,而不必下载外部样式表。 顺便说一下,这是字体加载晚于必需时间的常见原因。
惊喜
由于特殊字体对于显示文本是必需的,因此浏览器必须将它们视为高优先级资源。
结果,我希望字体文件能很快加载。 无论如何,我的资源页面都很“浅”,因此我认为没有什么可以阻止字体文件的加载。
当我分析该站点时,我感到有些震惊。
因此,使用Chrome开发人员工具查看该网站并在Webpagetest中对其进行了检查,我发现在图像之后加载了高优先级字体-低优先级资源。
在下载字体之前先下载图像在我看来,这完全是胡扯。
我肯定知道浏览器在下载字体之前可以等待,直到发现显示该页面需要该字体。 但是,使用我的字体的元素位于页面的顶部,在
<header>
,比带有在下载字体之前加载的图像的标记高得多。 相应的元素不仅位于页面代码中,而且位于DOM树中。
预加载字体作为问题的解决方案
preload
属性告诉浏览器它需要预加载显示当前页面所需的相应资源。
使用此属性是提前下载重要资源的好方法,否则稍后浏览器会发现这些重要资源。
字体文件是使用此机制的一个很好的例子。 如果指向字体文件的链接是在外部样式表中进行的,则浏览器在加载该样式表之前将不会检测到该字体。
preload
将
preload
属性应用于字体文件时,它会告诉浏览器在显示页面时将需要适当的字体。
另外,使用
<link>
元素很容易实现这种机制。
<link rel="preload" href="myfont.woff2" as="font" type="font/woff2" crossorigin>
或者,您可以将preload指令添加到响应头中(尽管除非另有说明,否则某些服务器或CDN可能将此设计解释为
服务器启动的请求,以将资源传输到客户端)。
我没想到在此站点上必须使用资源预加载机制。 我的CSS代码非常适度,我将其嵌入到页面的HTML代码中,这样做是为了使浏览器在首次访问该网站时可以更快地显示页面。 由于我的字体不依赖于加载外部CSS文件,因此,无论如何,浏览器都应该很早就检测到它,而没有关于预加载的“提示”。
但是,我发现预先加载字体会导致恢复正义,这是因为在下载图像文件之前已经加载了字体文件。
这是Webpagetest的瀑布图-我突出显示了显示字体文件的地方。 在图的顶部,未使用预加载。 在底部-使用。
预加载并使用字体文件。考虑页面加载过程的情节提要可能会更有用(在这里,为清楚起见,使用了非常慢的连接的模仿)。
在顶部情节提要中,不使用预加载。 在底部-使用顺便说一句,我注意到我使用了
font-display: fallback
句柄。 也就是说,标题最初是使用备用字体显示的,以防我的字体加载缓慢。 但是,在此测试中,我关闭了此功能,因为否则很难区分加载页面的步骤。
为什么行得通?
为了显示网页,浏览器需要构建DOM树和CSSOM树,稍后将它们用于构建渲染树。
preload
将
<link>
元素与
preload
属性一起使用来下载字体,
preload
允许浏览器在DOM完成之前开始构建CSSOM。
您可以在以下图像中看到这一点,这些图像显示了使用Chrome开发人员工具进行页面加载过程的过程。
这是在不使用预加载的情况下使用页面材料的样子。 首先,创建DOM并加载图像,然后创建CSSOM并加载字体。
使用页面而不使用预加载和这里一样,只是使用了预加载。 在这里,浏览器开始创建CSSOM,开始下载字体,然后创建DOM并开始下载图像。
使用预加载处理页面是否有替代预加载的方法?
假设我无法使用
preload
属性来增加字体文件的优先级。 那我该怎么办? 您如何降低图像的优先级?
出于好奇,我尝试实现上述想法,并将属性
loading="lazy"
到描述图像的元素中。 在Chrome 76(撰写本文时唯一支持此功能的浏览器)中,这将不得不降低页面原始可见区域之外的图像的优先级。
使用开发人员工具测试此想法已表明,这导致较早下载字体。 也许这值得记住,因为浏览器对延迟加载机制的支持水平随着时间的增长而增长。
不同的浏览器行为不同
我在几种不同的浏览器和多种设备上测试了该项目。 在测试中,我发现iOS Safari(iPhone 8)的行为与Chrome相同。 即,默认情况下,字体会在图像之后加载,但是使用
preload
属性可以解决这种情况。
在Firefox中也出现了字体较晚加载的问题,但是默认情况下此浏览器尚不支持
preload
属性,因此在Firefox中查看网站时使用
preload
属性没有任何更改。
在Edge中,字体加载的时间也比预期的要晚。 感觉使用Webload Pagetest和
preload
属性只能部分起作用。 即,在我看来,它看起来像是双字体下载。 一旦加载较早,则第二次加载。
在上一段中,我谈到了我“有一种感觉”和我“似乎”出现的事实。 事实是,当我尝试使用自己的Edge版本测试此行为时,“双重”下载消失了。 现在,我感觉使用
preload
属性
preload
加快字体加载速度。 页面行为上的这种差异可能是由于在Edge中修复了一些错误而导致的,尽管如果是这样,则以更改资源预加载机制为代价来纠正错误。
总结
在这里,我们讨论了为什么即使在页面中嵌入的CSS代码中建立了指向其文件的链接,也不会损害预加载字体的原因。
浏览器的行为并不总是像我们期望的那样,也不总是像我们期望的那样。 但是,我们有一些工具可以帮助影响浏览器的行为,并有助于将其引导到所需的方向。
我曾经认为在我的网站上预加载字体是完全没有意义的。 从我所说的一切中,我为自己学到了重要的一课。 它包含以下事实:您永远都不应承担任何责任。
最后,我可以说预加载字体是加快网页上文本输出速度的好方法。
亲爱的读者们! 您是否在Web项目中使用字体预加载机制?
