自从使用 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;
}
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet'>
Georgian
网络字体。我正在使用 font-squirrel 方法,我也希望看到这个问题的一个很好的答案。
@font-face
声明的非常好的文章,也许您可以找到有用的信息。 paulirish.com/2009/bulletproof-font-face-implementation-syntax
首先,我要澄清一下 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>
在许多情况下,script1
、style1
和 style2
会被阻止。这意味着浏览器在加载该资源之前无法继续显示文档(尽管现代浏览器对此稍加修改)。这实际上是一件好事,尤其是对于样式表。它可以防止无样式内容的闪现,还可以防止在应用样式时发生巨大的变化(而且变化的内容对于用户来说真的很烦人)。
另一方面,script2
不会阻塞。它可以稍后加载,浏览器可以继续解析和显示文档的其余部分。所以这也是有益的。
特别是谈到字体(更具体地说,是 Google 的产品),我可能会坚持使用 CSS 方法(我喜欢 @import
,因为它使用样式表保持样式,但可能只是我)。脚本 (http://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js) 加载的 JS 文件比 @font-face
声明大,只是 看起来 需要更多的工作。而且我不相信加载实际字体本身(WOFF 或 TTF)会阻塞,所以它不应该延迟太多。我个人不是 CDN 的忠实粉丝,但事实是它们真的很快。谷歌的服务器将以压倒性优势击败大多数共享托管计划,而且由于它们的字体非常受欢迎,人们甚至可能已经将它们缓存起来。
这就是我所拥有的。
我没有使用 Typekit 的经验,所以我把它排除在我的理论之外。如果有任何不准确之处,不计算浏览器之间的泛化,请指出。
我认为您在问题中已经很好地解决了加载时间问题。从我的角度来看,应该将一些来源添加到列表中,并且应该检查一些其他考虑因素以全面了解这些选项。
其他一些著名的字体来源
云排版
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:简单的测试,一旦部署就需要更多的改变
好吧,正如你所追求的
...在这里寻找最佳实践,性能是一件大事,但可扩展性和易用性也是如此。更不用说,外观和感觉。
答案是(就像在网页设计中一样):这取决于!
可以肯定的一件事是,我不建议使用 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 示例和操作说明!
我使用内联css方法是因为额外请求的开销超过了bease64编码时的大小增加。这也被 css 文件服务器的 gizip 压缩进一步抵消。
其他选项是使用异步加载字体,但大多数情况下用户会在加载后看到字体弹出。
无论采用哪种方法,您都可以通过仅包含您将使用的字符集来减小字体文件的大小。
我个人使用谷歌字体。他们有多种选择,最近也有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 是一个非常快速的字体源。我很快就会在这里发布速度测试。
最好的选择是使用 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 分。
async
属性呢?它做同样的事情。