ChatGPT解决这个技术问题 Extra ChatGPT

Webfonts 还是本地加载的字体?

自从使用 Cufon 带来的麻烦之后,我就不再使用外部字体资源,但最近,我一直在寻找加载字体的替代方法,看看是否有更好的方法;更好的方法有一种突然出现的方式。

那里有很多新方法,而且似乎每种方法都有变化;我应该使用打字机吗?或 google webfonts(使用 js 或 css)?我应该继续使用本地加载字体(例如 fontsquirrel.com 生成的方法)吗?

我将在下面列出似乎最受好评的方法,并进行一些测试,但是真的值得转向网络字体吗?看起来它会承载更高的资源负载(http请求)并且文件格式类型更少(兼容性更差)等。但看起来文件在大多数情况下是异步且有效地加载的。

只是情况和需要的问题吗?如果是这样,它们是什么?这些方法之间是否存在巨大差异?有没有更好的方法我没有列出?性能的优缺点是什么?看?依赖?兼容性?

我真的在这里寻找最佳实践,性能很重要,但可扩展性和易用性也很重要。更不用说,外观和感觉。

谷歌 CSS

只使用外部样式表

仅使用最小的兼容文件类型

可以使用 @import 或 或获取样式表 (@font-face) 的内容并将其直接放入您自己的样式表中。

试验结果

78ms 加载 html 36ms 加载 css

https://i.stack.imgur.com/ARy4Y.jpg

谷歌JS方法

使用 webfont.js 加载样式表

仅使用最小的兼容文件类型

将 :root 元素附加到类

将脚本添加到头部。

试验结果

171ms 加载 html 176ms 加载 js 32ms 加载 css

https://i.stack.imgur.com/E6eCr.jpg

打字机方法

将 :root 元素附加到类。

可以使用 *.js 片段或外部加载的文件 *.js 文件

使用 data:font/opentype 而不是字体文件。

将脚本添加到头部

将嵌入式 CSS 添加到头部

向头部添加外部样式表,您可以从 typekit.com 轻松添加/删除/调整字体和目标选择器

试验结果

169ms 加载 html 213ms 加载 js 31ms 加载 css 3ms 加载数据:字体/

https://i.stack.imgur.com/gEVPu.jpg

…&字体松鼠方法

@font-face{
    font-weight:400;
    font-style:normal;
    font-family:open_sanslight;
    src:url(../font/opensans-light-webfont.eot);
    src:url(../font/opensans-light-webfont.eot?#iefix) format(embedded-opentype),
        url(../font/opensans-light-webfont.woff) format(woff),
        url(../font/opensans-light-webfont.ttf) format(truetype),
        url(../font/opensans-light-webfont.svg#open_sanslight) format(svg)
}

…或者使用 data:font 方法…

@font-face {
    font-family: 'open_sanslight';
    src: url('opensans-light-webfont-f.eot');
}

@font-face {
    font-family: 'open_sanslight';
    src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAF4sABMAAAAArXQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABqAAAABwAAAAcZLn0KkqwK44Jq866WBSpzpsNY2IyGAhoJFBbYjuxmyns5sNa4NwldcJ7eh3Uy5gQkURIlqWzONe3HcLsDX1x/+jifDXvbzgTBjopZElndil3hJkERJkmRJkVRJk3TJkEzJkmzOc4HLXOEOF7nEX/*thisisnotafullencodingjustanexample*/bZwUnK4yS3JlTx2Sr4USKEUSbHVX9fcGNBs4fqgw+GoNHU7lKr36Eqn0lCWt6pHFpWaUlc6lS6loSxRlirLlP/uuU01dVfT7L6gPxyqraluCpgj3WtqeC1V4VBDW2N4K1r1esw/IupKp9L1FwlqnuIAAAB42j3NvQ7BUBjG8R5tTz/0u2UjNTTESYQbMGmXLiISbeI6zBYjbuWtye7CeMJxtuf3LP8ne1+IXbWa7G3TMXZru4qLZkJRW1O2wzi3I+Li2Gik5yXpYkNGXj70YU98YQLGHxwwXxIWwO8SNmAdJBzAXku4gFNI9AF38QMjTwZ9vN6yJzq9OoEB6I8VQzDYK0ZguFKMwWiumIDxTDEFk6liBqaF4gDMFFvKxAfOxFUGAAABUxSL9gAA) format('woff'),
         url('opensans-light-webfont-f.ttf') format('truetype'),
         url('opensans-light-webfont-f.svg#open_sanslight') format('svg');
    font-weight: normal;
    font-style: normal;

}
这是一个很好的问题。
我不确定这是否是最好的方法,但我总是像这样使用 Google CSS <link href='http://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet'>
我开发了一个类似 font-squirrel 的网站,仅适用于本地 Georgian 网络字体。我正在使用 font-squirrel 方法,我也希望看到这个问题的一个很好的答案。
这是一篇关于如何声明防弹 @font-face 声明的非常好的文章,也许您可以找到有用的信息。 paulirish.com/2009/bulletproof-font-face-implementation-syntax
如果您在此之前不接受,我可以开始赏金以获得更好/改进的答案。

Z
ZachRabbit

首先,我要澄清一下 Google 的产品。它实际上会加载您的浏览器可以处理的最小格式。 WOFF 提供小文件大小,并且您的浏览器支持它,所以它就是您所看到的。 WOFF 也得到相当广泛的支持。但是,例如在 Opera 中,您可能会获得 TrueType 版本的字体。

我相信,文件大小逻辑也是 Font Squirrel 以这种顺序尝试它们的原因。但这主要是我的猜测。

如果您在每个请求和字节都很重要的环境中工作,则必须进行一些分析以找出最适合您的用例的环境。人们会只查看一个页面,而不再访问吗?如果是这样,缓存规则就没有那么重要了。如果他们正在浏览或返回,Google 可能有比您的服务器更好的缓存规则。延迟是更大的问题,还是带宽?如果存在延迟,则以更少的请求为目标,因此将其托管在本地并尽可能多地组合文件。如果带宽,请选择以最小代码和最小字体格式结束的选项。

现在,关于 CSS 与 JS 的考虑。让我们看一下以下 HTML:

<head>
    <script type="text/javascript" src="script1.js"></script>
    <link rel="stylesheet" type="text/css" href="style1.css" />
    <style type="text/css">
        @import url(style2.css);
    </style>
    <script type="text/javascript">
        (function() {
            var wf = document.createElement('script');
            wf.src = 'script2.js';
            wf.type = 'text/javascript';
            wf.async = 'true';
            var s = document.getElementsByTagName('script')[0];
            s.parentNode.insertBefore(wf, s);
        })();
    </script>
</head>

在许多情况下,script1style1style2 会被阻止。这意味着浏览器在加载该资源之前无法继续显示文档(尽管现代浏览器对此稍加修改)。这实际上是一件好事,尤其是对于样式表。它可以防止无样式内容的闪现,还可以防止在应用样式时发生巨大的变化(而且变化的内容对于用户来说真的很烦人)。

另一方面,script2 不会阻塞。它可以稍后加载,浏览器可以继续解析和显示文档的其余部分。所以这也是有益的。

特别是谈到字体(更具体地说,是 Google 的产品),我可能会坚持使用 CSS 方法(我喜欢 @import,因为它使用样式表保持样式,但可能只是我)。脚本 (http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js) 加载的 JS 文件比 @font-face 声明大,只是 看起来 需要更多的工作。而且我不相信加载实际字体本身(WOFF 或 TTF)会阻塞,所以它不应该延迟太多。我个人不是 CDN 的忠实粉丝,但事实是它们真的很快。谷歌的服务器将以压倒性优势击败大多数共享托管计划,而且由于它们的字体非常受欢迎,人们甚至可能已经将它们缓存起来。

这就是我所拥有的。

我没有使用 Typekit 的经验,所以我把它排除在我的理论之外。如果有任何不准确之处,不计算浏览器之间的泛化,请指出。


我认为在很大程度上这大部分都是情境性的,但你也对阻塞和 FOUT 问题做了很好的说明。我在这里读到了:paulirish.com/2009/fighting-the-font-face-fout & stevesouders.com/blog/2009/10/13/font-face-and-performance。今晚我将进行一些测试并发布性能差异。感谢您的深刻见解。
n
nwalton

我认为您在问题中已经很好地解决了加载时间问题。从我的角度来看,应该将一些来源添加到列表中,并且应该检查一些其他考虑因素以全面了解这些选项。

其他一些著名的字体来源

云排版

http://www.typography.com/cloud/

据我所知,字体作为数据嵌入到 CSS 文件中:

@font-face{ 
    font-family: "Font Name"; 
    src: url(data:application/x-font-woff;base64,d09GRk9UVE8AACSCAA0AAAAARKwAAQAAAAAiVAAAAi4AAAadAAAAAAAAAABDRkYgAAAIyAAAFCgAABmIK5m+CkdERUYAABzwAAAAHQAAACAAXQAER1BPUwAAHRAAAAQlAAAYAq+OkMNHU1VC ... ); 
    font-weight:400; font-style:normal; 
} 

这是我的规格:

94ms load of css from their server
37ms load of css from our server (will vary based on your configuration)
195ms load of data:fonts from our server (will vary based on your configuration)

Here is their very high-level description of their deployment

字体网

我没有使用过这项服务,但他们是一家非常成熟的字体供应商,他们在其网站上列出的信息令人印象深刻。我没有关于他们确切方法的规范,但这是我所知道的:

世界上一些最知名的字体

一个非常大的字体库(超过 20,000 个)

用于制作模型的桌面字体下载

用于在浏览器中测试网络字体的自定义工具

精细的排版控制和子集

自托管选项

字体弹簧

隶属于 FontSquirrel。字体可以在这里以固定价格购买。附带 CSS 的字体文件被交付,部署在您自己的服务器上,很像 FontSquirrel。

扩展规格

至于每种字体服务的整体优缺点,这里有一些比较:

字体库大小

Fonts.com:20,000+

字体弹簧:1000+

字体松鼠:300+

谷歌:600+

打字机:900+

Typography.com (cloud.typography.com):大概 300+(35 个家庭)

价钱

Fonts.com:500,000 次页面浏览量每月 20 美元

FontSpring:因字体而异(一次性购买字体)

字体松鼠:免费

谷歌:免费

Typekit:500,000 次页面浏览量每月 4 美元

Typography.com:1,000,000 次页面浏览量每月 12.50 美元

字体质量

网络字体的质量可能会有很大差异。这可以包括诸如字母本身或字符集的间距或大小之类的东西。所有这些都决定了字体给人的整体质量印象。虽然免费选项有一些不错的选择,但它们也有一些质量不高的字体,因此您需要从这些来源中谨慎选择。

Fonts.com:高

FontSpring:混合到高

字体松鼠:混合

谷歌:混合

类型套件:高

Typography.com:非常高(我给它一个“非常高”的名称,因为 Fonts.com、FontSpring 和 Typekit 支持多种字体代工厂,其中只有 H&FJ 代工厂的字体,这是世界上最好的字体之一)

字体质量 II:排版

桌面排版有很多改进,在网络字体中很难做到。其中一些服务提供了提供这些服务的方式。

Fonts.com:字距调整、字母间距、连字、替代字符、分数等。

字体弹簧:无

字体松鼠:无

谷歌:无

打字机:无

Typography.com:小型大写字母、连字、交替字符、交替数字样式、分数等。

浏览器支持

这主要归结为每个服务支持的字体格式。主要的有:

EOT:用于 Internet Explorer (IE 4+)

TrueType 和 OpenType:传统格式(Safari 3.1+、FF 3.5+、Opera 10+)

WOFF:网络字体的新标准(FF 3.6+、Chrome 5+)

SVG:IOS <4.2

The @Font-Face Rule And Useful Web Font Tricks 上的更多信息

所有这些服务都支持主要的字体格式。使用自托管字体,只要您使用正确的语法,您就应该被覆盖。以下是来自 FontSpring 的防弹语法 2011 年更新:

@font-face {
  font-family: 'MyWebFont';
  src: url('webfont.eot'); /* IE9 Compat Modes */
  src: url('webfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('webfont.woff') format('woff'), /* Modern Browsers */
       url('webfont.ttf')  format('truetype'), /* Safari, Android, iOS */
       url('webfont.svg#svgFontName') format('svg'); /* Legacy iOS */
  }

表现一:下载

据我了解,使用上述语法允许浏览器获取适用于它们的特定格式,因此不会浪费下载不起作用的字体格式。

Fonts.com、Typekit 或 Typography.com 等付费服务使用方法来检测正确的格式,然后提供正确的字体格式,通常是 CSS 文件中的 base64 数据。

据我所知,您上面列出的方法的差异对于高速互联网用户来说可以忽略不计(似乎差异小于 200 毫秒),但对于较慢网络上的设备,尤其是对于未缓存的页面点击,可能值得考虑。

表现二:子集

如果您知道只会使用某些字符,则可以使用字符子集构建字体,从而减少下载的大小。

Fonts.com:非常详细的控制

FontSpring:可以通过 FontSquirrel webfont 生成器重新编译为子集

FontSquirrel:可以通过 webfont 生成器重新编译为子集

谷歌:非常详细的控制

Typekit:“所有字符”或“默认”的有限选项

Typography.com:非常详细的控制

业绩三:交付

Fonts.com:全球 CDN 或您自己的服务器

FontSpring:基于您的服务器

FontSquirrel:基于你的服务器

谷歌:全球超级CDN

Typekit:全球 CDN

Typography.com:全球 CDN(125,000 台服务器)

语言支持

Fonts.com:40 种语言,包括亚洲和中东

FontSpring:西方,取决于字体

FontSquirrel:西方,取决于字体

谷歌:西方,取决于字体

Typekit:西文,取决于字体

Typography.com:西方,取决于字体

测试和实施

Fonts.com:非常简单,具有广泛且可定制的工具

FontSpring:技术(自己动手)

FontSquirrel:技术(自己动手)

谷歌:简单

打字机:简单

Typography.com:简单的测试,一旦部署就需要更多的改变


这并不能回答 OP 的问题。它只是比较了几种 Webfonts。
这是有关每个供应商的信息最丰富的信息,感谢您提供的所有信息!
N
Netsurfer

好吧,正如你所追求的

...在这里寻找最佳实践,性能是一件大事,但可扩展性和易用性也是如此。更不用说,外观和感觉。

答案是(就像在网页设计中一样):这取决于!

可以肯定的一件事是,我不建议使用 JS 方法(如您的第二个示例所示)。

就我个人而言,我不喜欢根据 Javascript 制作展示性的东西和 CSS 样式,尽管绝大多数用户都启用了它。这是一个不要混淆的问题。

正如您在给定示例中看到的那样,存在某种 FOUC(未设置样式的内容),因为该页面在字体可用之前已经由浏览器呈现。一旦它是,页面被重绘。网站越大,(性能)影响就越大!

所以我永远不会使用任何 JS 解决方案来嵌入字体。

现在让我们看一下纯 CSS 方法。
很长一段时间以来,这里一直在讨论“与 @import”。就我个人而言,我更喜欢避免使用 @import 并且始终只使用 <link>。但这主要是个人喜好的问题。你永远不应该做的一件事就是将它们混合在一起!

本地与 CDN 在决定是在本地托管字体文件还是使用 CDN 时,恕我直言,这主要取决于不同字体的数量以及要嵌入的相应字体。

为什么这很重要,或者起作用?从性能的角度来看,我建议在您的(一个)样式表中包含编码的字体 Base64。但只有 .woff 格式,因为几乎所有现代浏览器都使用这种格式,这意味着您的大多数访问者。对于所有其他用户来说,需要额外的请求。

但是由于 Base64 编码和字体文件的大小(即使是 .woff 格式)造成的“开销”,只有在您拥有不超过 3 或 4 种不同字体的情况下才应该使用这种技术。并且始终确保您的服务器提供经过 gzip 压缩的 (CSS) 文件。

这样做的最大好处是您没有对字体文件的额外请求。在第一个页面加载后(无论您网站的哪个页面),CSS 文件都会被缓存。如果您使用 HTML5 应用程序缓存(您肯定会这样做),这也是一个优势。

除了一个作者在他的网站上最多不能使用超过 3 或 4 种不同的字体这一事实之外,让我们看看使用 Google 的 CDN 的方法。

首先请注意,您可以(并且始终应该)将所有需要的字体包含在一个 <link> 中,如下所示:

<link href='http://fonts.googleapis.com/css?family=PT+Serif:400,700,400italic,700italic|PT+Sans:400,700,400italic,700italic|Montez' rel='stylesheet' type='text/css'>

这将导致以下响应:

@font-face {
  font-family: 'Montez';
  font-style: normal;
  font-weight: 400;
  src: local('Montez'), local('Montez-Regular'), url(http://themes.googleusercontent.com/static/fonts/montez/v4/Zfcl-OLECD6-4EcdWMp-Tw.woff) format('woff');
}
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 400;
  src: local('PT Sans'), local('PTSans-Regular'), url(http://themes.googleusercontent.com/static/fonts/ptsans/v6/LKf8nhXsWg5ybwEGXk8UBQ.woff) format('woff');
}
@font-face {
  font-family: 'PT Sans';
  font-style: normal;
  font-weight: 700;
  src: local('PT Sans Bold'), local('PTSans-Bold'), url(http://themes.googleusercontent.com/static/fonts/ptsans/v6/0XxGQsSc1g4rdRdjJKZrNBsxEYwM7FgeyaSgU71cLG0.woff) format('woff');
}
@font-face {
  font-family: 'PT Sans';
  font-style: italic;
  font-weight: 400;
  src: local('PT Sans Italic'), local('PTSans-Italic'), url(http://themes.googleusercontent.com/static/fonts/ptsans/v6/PIPMHY90P7jtyjpXuZ2cLD8E0i7KZn-EPnyo3HZu7kw.woff) format('woff');
}
@font-face {
  font-family: 'PT Sans';
  font-style: italic;
  font-weight: 700;
  src: local('PT Sans Bold Italic'), local('PTSans-BoldItalic'), url(http://themes.googleusercontent.com/static/fonts/ptsans/v6/lILlYDvubYemzYzN7GbLkHhCUOGz7vYGh680lGh-uXM.woff) format('woff');
}
@font-face {
  font-family: 'PT Serif';
  font-style: normal;
  font-weight: 400;
  src: local('PT Serif'), local('PTSerif-Regular'), url(http://themes.googleusercontent.com/static/fonts/ptserif/v6/sDRi4fY9bOiJUbgq53yZCfesZW2xOQ-xsNqO47m55DA.woff) format('woff');
}
@font-face {
  font-family: 'PT Serif';
  font-style: normal;
  font-weight: 700;
  src: local('PT Serif Bold'), local('PTSerif-Bold'), url(http://themes.googleusercontent.com/static/fonts/ptserif/v6/QABk9IxT-LFTJ_dQzv7xpIbN6UDyHWBl620a-IRfuBk.woff) format('woff');
}
@font-face {
  font-family: 'PT Serif';
  font-style: italic;
  font-weight: 400;
  src: local('PT Serif Italic'), local('PTSerif-Italic'), url(http://themes.googleusercontent.com/static/fonts/ptserif/v6/03aPdn7fFF3H6ngCgAlQzBsxEYwM7FgeyaSgU71cLG0.woff) format('woff');
}
@font-face {
  font-family: 'PT Serif';
  font-style: italic;
  font-weight: 700;
  src: local('PT Serif Bold Italic'), local('PTSerif-BoldItalic'), url(http://themes.googleusercontent.com/static/fonts/ptserif/v6/Foydq9xJp--nfYIx2TBz9QFhaRv2pGgT5Kf0An0s4MM.woff) format('woff');
}

如您所见,如果用户没有在本地安装一种或多种请求的字体,则共有 9 个不同的字体文件,这意味着总共有 10 个(包括链接元素之一)请求。并且这些请求在您网站的每个新页面请求时都会重复(尽管不再传输数据)!此外,对 <link> 的请求的响应也不会被缓存。

建议:毕竟,我真的建议您在样式表中包含 .woff 格式 Base64 编码的字体文件!

See this nice article 示例和操作说明!


非常感谢,正在寻找这个解决方案!
C
Chris Gunawardena

我使用内联css方法是因为额外请求的开销超过了bease64编码时的大小增加。这也被 css 文件服务器的 gizip 压缩进一步抵消。

其他选项是使用异步加载字体,但大多数情况下用户会在加载后看到字体弹出。

无论采用哪种方法,您都可以通过仅包含您将使用的字符集来减小字体文件的大小。


使用 HTTP2 时没有上面提到的额外开销。
J
Jeremy Karlsson

我个人使用谷歌字体。他们有多种选择,最近也有improved compression on the fonts by moving to Zopfli compression。谷歌正在努力让网络更快,所以我想这部分的更多优化也将来自他们。

无论您选择什么作为外包字体交付,您总是会因获取字体的请求而降低速度。从速度的角度来看,最好的办法是自己提供字体。如果您不关心从外包交付中加载所需的额外毫秒数,那么如果您认为使用它们的易用性值得花费数毫秒,那么您应该这样做。

我不了解 Typekit 和其他人,但使用 Google 字体,您可以选择提供特定的子集和字符范围,以进一步加快交付速度。

选择子集:

<link href="http://fonts.googleapis.com/css?family=Open+Sans&subset=latin" rel="stylesheet">

选择字符范围:

<!-- Only serve H,W,e,l,o,r and d -->
<link href="http://fonts.googleapis.com/css?family=Open+Sans&text=HelloWorld" rel="stylesheet">

您可以使用 dns-prefetch 通过字体交付进一步提高速度。

我确实认为并希望谷歌会尽其所能来加快他们的字体交付速度。加载它们所需的毫秒数不会损害我的网站,所以我很乐意使用它们。

长话短说:

如果字体交付所需的毫秒数损害了您的网站,例如使其加载时间超过建议的 1 秒,我认为您应该自己托管它们。


关于<link rel=dns-prefetch href='//fonts.googleapis.com'>的好点我将它用于分析、热图和子域,由于某种原因,它没有注册为外部网络字体运行。并且加载时间因字体而异,我想如果您使用的是相当流行的字体(可能被缓存)或仅选择少数几种字体,那么使用 webfonts 是一个非常快速的字体源。我很快就会在这里发布速度测试。
P
Phok7

最好的选择是使用 ajax 导入字体,就像这样:

<script>
    (function() {
        var font = document.createElement('link'); 
        font.type = 'text/css'; 
        font.rel = 'stylesheet';
        font.href = '/url/to/font.css';
        var s = document.getElementsByTagName('link')[0]; 
        s.parentNode.insertBefore(font, s);
      })();
</script>

我在我的网页上执行此操作,并在 Google Insights 测试中提高了 9 分。


有趣的。我将不得不用这种方法研究 PageSpeeds。
async 属性呢?它做同样的事情。

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅