预加载字体

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

当他创建一个网站时,他将该材料的原始版本发布在该网站上,但他不会在该网站上使用任何自己的字体。 尽管影响不大,但这将不可避免地影响站点性能。 文章的作者说,他努力建立一个快速的网站。 但是,最终决定对页面标题使用一种特殊的字体,同时尝试使此解决方案对项目性能的影响尽可能小。

开始使用


首先,我决定使字体文件尽可能小。 所以我创建了这种字体的一个子集。 换句话说,我仅从字体中选择了标题中单词所必需的那些字符。

结果,我得到了一个非常紧凑的文件,其大小小于2 Kb。 此外,我将其与网站上所有其他材料放置在同一位置,这使我摆脱了第三方依赖关系以及连接到另一个域所花费的时间。

最后,字体文件的链接放置在页面中嵌入的CSS代码中,HTML代码的顶部,而不是外部CSS文件中。

这意味着浏览器可以检测并下载字体文件,而不必下载外部样式表。 顺便说一下,这是字体加载晚于必需时间的常见原因。

惊喜


由于特殊字体对于显示文本是必需的,因此浏览器必须将它们视为高优先级资源。

结果,我希望字体文件能很快加载。 无论如何,我的资源页面都很“浅”,因此我认为没有什么可以阻止字体文件的加载。

当我分析该站点时,我感到有些震惊。

因此,使用Chrome开发人员工具查看该网站并在Webpagetest中对其进行了检查,我发现在图像之后加载了高优先级字体-低优先级资源。


在下载字体之前先下载图像

在我看来,这完全是胡扯。

我肯定知道浏览器在下载字体之前可以等待,直到发现显示该页面需要该字体。 但是,使用我的字体的元素位于页面的顶部,在<header> ,比带有在下载字体之前加载的图像的标记高得多。 相应的元素不仅位于页面代码中,而且位于DOM树中。

预加载字体作为问题的解决方案


preload属性告诉浏览器它需要预加载显示当前页面所需的相应资源。

使用此属性是提前下载重要资源的好方法,否则稍后浏览器会发现这些重要资源。

字体文件是使用此机制的一个很好的例子。 如果指向字体文件的链接是在外部样式表中进行的,则浏览器在加载该样式表之前将不会检测到该字体。

preloadpreload属性应用于字体文件时,它会告诉浏览器在显示页面时将需要适当的字体。
另外,使用<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项目中使用字体预加载机制?


Source: https://habr.com/ru/post/zh-CN470870/


All Articles