使用过多的字体声明是否会对性能产生影响?

Is there any performance impact of using too many font-face declarations?

问题:

如果 CSS 文件中有大量字体列表(比如超过 2000 个),浏览器从 "big list" 中挑选字体以应用到 HTML 块? 请忽略字体文件大小、网络延迟、缓存或其他一切。

详情:

我正在开发一个开源项目,以创建一个 CSS 文件,其中包含 fonts.google.com 上托管的所有字体的字体。原因是为了使字体包含变得简单和跨项目,即在每个项目中只包含相同的单个 CSS 文件,然后就可以了。

我担心过多的字体声明会影响性能。整体 CSS 文件大小将小于 25KB Gzipped,所以我可以接受。但是将会有 1950 多种字体,这可能会使某些浏览器在现实世界中变慢。

尽管这些字体文件 不会被浏览器下载 除非它们确实在 HTML 文档中使用,所以这不是问题。我只关心浏览器在内存中处理这些字体声明以及在 CSS.

中使用时有效引用它们的效率

有人能帮忙吗?

编辑:

这是我打算使用的 css 文件:https://raw.githubusercontent.com/praisedpk/Local-Google-Fonts/master/google-fonts/webfonts.css

它来自 github 回购:Local Google Fonts

是的,有性能影响,但不是特别高。

为了衡量影响,我使用了 Chrome 的“Inspect”选项和“Network”选项卡。 (其他选项也可用于执行此操作。)

我在选中“禁用缓存”按钮后转到了提供的link。这样做可以让您衡量第一次下载文件的全部影响。

这表明 webfonts.css 文件的大小为 17.9 KB,我的系统使用 Chrome 在 26 毫秒内下载了它。 (还不错,但这完全取决于您的判断力。)

如果将鼠标悬停在 "Waterfall" 时间栏上,您可以看到有关此文件下载到浏览器的更多详细信息。

在您发布的页面的响应 header 中使用 cache-control 设置来通知浏览器在检查更新版本之前缓存的 CSS 文件可以重复使用多长时间。

例如,使用 SO 网站并使用 Chrome 的 Inspect 函数查看下载的 CSS 文件,max-age 值定义了 604,800 秒(1 周)。

要像之前的图像一样显示,请单击 Chrome 的 Inspect[的“Network”选项卡中列出的文件实用程序。

我相信 max-age 持续时间会通知浏览器在需要检查是否有更新的文件可用之前可以使用当前缓存的文件多长时间。在某些情况下,最好将此持续时间短得多。

有关此的更多信息,请访问此 MDN page on Cache-Control

还有许多主题为 cache-control 的 SO 条目可能适用于您网站的环境。

你要考虑两个方面:网络和浏览器的渲染。当您加载大量字体时,这两个方面都会对性能产生影响。 Google 在 https://fonts.google.com/ 上有同样的问题 - 他们已经很好地解决了。

让我们看看他们做了什么。我们打开Chrome,打开https://fonts.google.com/,按F12打开开发者工具,按F5重新打开页面。现在切换到网络选项卡以查看已加载哪些文件。惊喜:只加载了大约 25 种字体。

现在向下滚动页面以查看更多字体示例 - 并观看网络选项卡。向下滚动时,您会看到 Google 加载了越来越多的字体。 这叫做"loading on demand"。有关详细信息,请参阅此 SO 主题:Load fonts on demand

var link = document.createElement("link")
link.setAttribute("rel", "stylesheet")
link.setAttribute("type", "text/css")
link.setAttribute("href", "http://fonts.googleapis.com/css?family=Indie+Flower")
document.getElementsByTagName("head")[0].appendChild(link)

因此 Google 监视页面的哪些部分当前可见并立即加载字体。当然,当用户重新访问该网站时,他们还应用缓存 headers 来加快此过程。

要检测您网站的某个部分是否在视图中,您可以使用如下脚本:https://plnkr.co/edit/91gybbZ7sYVELEYvy1IK?p=preview

$(document).ready(function() {
  myElement = $('.someObject');
  window.onscroll = function() {

    var screenTop = $(window).scrollTop();
    var screenBottom = screenTop + $(window).height();    
    var elTop = $(myElement).offset().top;
    var elBottom = elTop + $(myElement).height();

    var info = 'screenTop:' + screenTop + ' screenBottom:' + screenBottom + ' elTop:' + elTop + ' elBottom:' + elBottom;

    if((elBottom <= screenBottom) && (elTop >= screenTop)) {
      $('.info').html('Element is in view + <small>' + info + '</small>');
    } else {
      $('.info').html('Element is out of view + <small>' + info + '</small>');
    }

  }
})

如果我对你的问题的理解正确,你不是在询问网络加载时间,而是在select加载列表中正确的字体声明的时间。

从 css 文件到 select 字体的时间可以忽略不计。加载站点时几乎所有其他操作都将花费更多时间。如果您想使用您选择的浏览器对此进行测试,只需打开 css file in the browser 并搜索带有 CTRL+F 的任何字体。结果应在不到 100 毫秒内可见,即使在较旧的机器上也是如此。

无论如何,您应该考虑到并非所有浏览器的行为都相同,并且 Internet Explorer(或至少是旧版本)将下载您声明的每种字体。使用与否并不重要,因此如果网站应该跨浏览器兼容,那么您的项目将不是一个选项。