由于 Arial, Verdana, Garamond or Times New Roman 这些字体几乎在全部电脑上都有安装,因此之前每一个网站都使用他们来渲染文本。至今,虽然webfonts已经在互联网中获得广泛的使用,可是咱们依然不知道如何高效的加载他们。css
为了提供更好的用户体验,我写了一些怎么作才能高效加载webfonts的简单解决方法,这个方案的实施并不须要昂贵的硬件支持。html
主要从如下方案进行介绍:web
(1)使用woff字体格式(PS:多是EOT和TTF格式默认状况下不会进行压缩,然而WOFF格式具备内建压缩,并且WOFF格式的支持很普遍的缘由。);浏览器
(2)对于不支持webfonts的浏览器使用“web安全”字体(PS:使用前言中提到的一些几乎全部电脑都安装了的字体做为后备字体,保证用户可以正常浏览网页);缓存
(3)下载字体的“二进制”格式,而且优化它;安全
(4)使用你本身的字体库;网络
(5)将字体进行base64编码后,存放于CSS文件中;app
(6)若是用户本地没有网页请求的字体,那么就异步加载该字体,而且将该字体存储在localStorage中,以便第二次请求字体直接从localStorage中进行读取,避免字体加载带来的性能问题;异步
英文版本的做者 2014/10/09 更新内容web安全
若是你不相信以上方案可以优化网页的性能,那么我建立了2个Demo页面。可以测试他们在:资源加载、资源阻塞以及其余方面的问题。
经过 caniuse 的统计,有84%用户的浏览器支持WOFF字体格式。除此以外,不支持WOFF格式的浏览器包括:IE8及其如下、Android上的一些老浏览器。所以,这里提供的优化是针对于支持WOFF字体格式的现代浏览器的方案。对于旧浏览器依然使用后备字体来展示网页(好比:Arial = = PS如下:中文的话能够采用“simsun”,属于衬线字体),这将给用户带来更好的用户体验。
这两种方式会形成如下两个问题:
(1)额外的请求阻塞
(2)经过它们异步加载字体的时候会出现闪烁问题。
下面咱们将看处处理webfonts更好的方式。
选择一个webfonts本身使用。不幸的时没有任何一个licence容许这么干。不过值得庆幸的时咱们能够利用一些开源的字体,好比:Open Sans、Source Sans Pro。当你发现你想要的字体就可以下载它们的“二进制”文件(OTF或者TTF)。
这里推荐一个网站:Font Squirrel Webfont Generator
(PS:这个网站是用来处理字体的,有捐赠环节的哦~具体功能能够点进去尝试一下就知道了)
咱们可以选择一些额外的方式来移除一些字符。你可以选择你须要的一些字符出来使用。若是你的网页全是英文内容,那么你只须要选择一些基本字符;若是你得网页有中文,那么你可能须要全部的字符。(原文错误:Chineese -\> Chinese)
更重要的是最后生成咱们所须要的,包含了字体base64编码信息的CSS字体文件。
该CSS文件的大小取决于你选择的字符集合以及相关方面,也许该文件至关的大(最高可达100~300KB)。所以,使用gzip压缩以及设置强缓存的方式对于用户来讲是很重要的。
不过幸运的是只有当你网页的浏览者第一次访问该CSS文件的时候会发出请求。因为在第一次的时候,用户本地没有该字体文件,因此浏览器就会去异步加载他们,而且存储在localStorage中。当用户的网络环境较慢的状况下,可以看到后备字体以及webfonts渲染过程,不过这些只会发生在用户第一次访问你网页的时候。大多数用户不会太在乎这一细节。
当用户第二次网页页面的时候,浏览器将从localStorage中加载CSS文件内容,这种方式至关的快速(5~50ms)。在这种状况下用户看不到任何的闪烁,由于全部的操做将是同步进行的,这仅仅只须要几毫秒的时间。
因为我使用的是localStorage技术,因此只有客户端的代码。
(function(){ function addFont() { var style = document.createElement('style'); style.rel = 'stylesheet'; document.head.appendChild(style); style.textContent = localStorage.sourceSansPro; } try { if (localStorage.sourceSansPro) { // 若是localStorage中有该字体,就直接取出来加载 addFont(); } else { // 首次加载字体咱们须要异步加载它 var request = new XMLHttpRequest(); request.open('GET', '/path/to/source-sans-pro.woff.css', true); request.onload = function() { if (request.status >= 200 && request.status < 400) { // 保存到localStorage中,key=sourceSansPro localStorage.sourceSansPro = request.responseText; addFont(); } } request.send(); } } catch(ex) { // 这里处理一些同步加载woff功能的浏览器 // 避免当localStorage不可用的时候,那么将每次请求字体带来的闪烁问题 } }());
优化的流程图简图以下:
(1)解决了除用户第一次访问网页外,其他更屡次访问时候的请求阻塞问题;
(2)解决了除用户第一次访问网页外,其他访问的闪烁问题;
(3)减小了第一次请求页面的渲染时间;
(4)获得了在Google Page Speed Insights 和 WebPageTest.org 上更高的分数。
英文版本的做者说到本文缺乏一些细节的说明,可以在他博客中留言讨论。
英文版本的做者 2014/10/11 更新内容
经过内联Goole提供的CSS文件的方式,在Google Page Speed Insights中取得了99/100的分数。
英文版本的做者不赞同使用这种方式,由于这种方式会严重影响文本的渲染,所以咱们来深刻了解一下其中发生了什么。
(1)首先咱们定义一个内联的font faces。
<head> ... <style> @font-face { font-family: 'Source Sans Pro'; font-style: normal; font-weight: 400; src: local('Source Sans Pro'), local('SourceSansPro-Regular'), url(http://fonts.gstatic.com/s/sourcesanspro/v9/ODelI1aHBYDBqgeIAH2zlBBHWFfxJXS04xYOz0jw624.woff) format('woff'); } </style> ... </head>
(2)因为浏览器最开始不知道页面哪个地方会使用到该字体,因此不会去请求这个字体文件。
(3)浏览器要等待DOM和CSSOM构建完成。
(4)浏览器这时开始从Google Fonts请求字体文件,须要注意的是,这里会有一个来自于fonts.gstatic.com的额外DNS请求(PS:在国内的环境就不要想google字体的事情了,可使用360的公共CDN服务,很好用,改改URL就行)。
这个timeline说明在DOMContentLoaded事件以前,字体的加载已经开始了。
(5)若是上面的前面还不够糟糕,大多数浏览器将呈现空白文本,在不一样浏览器之间实际的行为会有所不一样:
A. 若是请求字体还不可用,IE 会当即使用后备字体呈现,并在字体下载完成以后立刻从新呈现;
B. Firefox 和 Chrome 35+ 会首先下载3秒钟的字体,若是超过3秒钟后,会使用后备字体渲染网页,等到指定字体下载完成后再从新渲染网页;
C. Safari 和 Chrome 35以前的版本,会等到指定字体下载完成后再渲染网页(PS:就是不会使用后备字体)。
注:以上说明中没有表示IE的版本以及Safari的版本号,因此须要本身测试才能算正确。
所以,若是网络链接缓慢,在大多数浏览器中将延迟超过3秒的文本渲染。在最坏的状况下,若是你的字体加载带有时间限制(因为一些链接很慢的移动设备),Safari 用户将不会再展现文本,剩下一个空白网页。若是网页请求超时,最终将只会呈现一个空白网页。
更多的信息能够访问:Ilya Gregorik's blog
其余相关资源:
其实英文版本的做者也是翻译的一篇俄文,这篇俄文来自于:
英文版本原文出自:
http://bdadam.com/blog/loading-webfonts-with-high-performance.html
注:若是你有兴趣能够再看一下英文版本和俄文版本文章下面的评论,里面还有一些颇有价值的东西,这里就再也不翻译了,有时间能够再整理一下。以上文章若是有翻译不恰当的地方请在文章后面留言,看见了必定回复而且修改。
原文出自:http://www.60sky.com