在响应式网站中,提高加载webfonts的性能(一)

前言

由于 Arial, Verdana, Garamond or Times New Roman 这些字体几乎在全部电脑上都有安装,因此之前每一个网站都使用他们来渲染文本。至今,虽然webfonts已经在互联网中获得广泛的使用,可是咱们依然不知道如何高效的加载他们。css

为了提供更好的用户体验,我写了一些怎么作才能高效加载webfonts的简单解决方法,这个方案的实施并不须要昂贵的硬件支持。html

0. 目录

主要从如下方案进行介绍: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页面。可以测试他们在:资源加载、资源阻塞以及其余方面的问题。

  1. Demo页面:从Google Fonts中加载字体

  2. Page Speed的测试:从Google Fonts中加载字体

  3. Demo页面:异步加载字体而且存储到localStorage中,第二次直接从localStorage中取出字体

  4. Page Speed的测试:异步加载字体而且存储到localStorage

页面访问截图

1. 浏览器支持程度

经过 caniuse 的统计,有84%用户的浏览器支持WOFF字体格式。除此以外,不支持WOFF格式的浏览器包括:IE8及其如下、Android上的一些老浏览器。所以,这里提供的优化是针对于支持WOFF字体格式的现代浏览器的方案。对于旧浏览器依然使用后备字体来展示网页(好比:Arial = = PS如下:中文的话能够采用“simsun”,属于衬线字体),这将给用户带来更好的用户体验。

2. 不要使用Google Fonts或者Typekit这类的外部连接方式

这两种方式会形成如下两个问题:

(1)额外的请求阻塞
(2)经过它们异步加载字体的时候会出现闪烁问题。

下面咱们将看处处理webfonts更好的方式。

3. licence问题

选择一个webfonts本身使用。不幸的时没有任何一个licence容许这么干。不过值得庆幸的时咱们能够利用一些开源的字体,好比:Open Sans、Source Sans Pro。当你发现你想要的字体就可以下载它们的“二进制”文件(OTF或者TTF)。

4. 优化、减少字体文件大小以及生成CSS文件

这里推荐一个网站:Font Squirrel Webfont Generator

(PS:这个网站是用来处理字体的,有捐赠环节的哦~具体功能能够点进去尝试一下就知道了)

咱们可以选择一些额外的方式来移除一些字符。你可以选择你须要的一些字符出来使用。若是你的网页全是英文内容,那么你只须要选择一些基本字符;若是你得网页有中文,那么你可能须要全部的字符。(原文错误:Chineese -\> Chinese)

更重要的是最后生成咱们所须要的,包含了字体base64编码信息的CSS字体文件。

5. 使用字体的CSS文件

该CSS文件的大小取决于你选择的字符集合以及相关方面,也许该文件至关的大(最高可达100~300KB)。所以,使用gzip压缩以及设置强缓存的方式对于用户来讲是很重要的。

不过幸运的是只有当你网页的浏览者第一次访问该CSS文件的时候会发出请求。因为在第一次的时候,用户本地没有该字体文件,因此浏览器就会去异步加载他们,而且存储在localStorage中。当用户的网络环境较慢的状况下,可以看到后备字体以及webfonts渲染过程,不过这些只会发生在用户第一次访问你网页的时候。大多数用户不会太在乎这一细节。

当用户第二次网页页面的时候,浏览器将从localStorage中加载CSS文件内容,这种方式至关的快速(5~50ms)。在这种状况下用户看不到任何的闪烁,由于全部的操做将是同步进行的,这仅仅只须要几毫秒的时间。

优化后的示例图

6. 展现一下代码的编写

因为我使用的是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不可用的时候,那么将每次请求字体带来的闪烁问题
    }
}());

优化的流程图简图以下:

优化的流程图

7. 咱们作到了什么

(1)解决了除用户第一次访问网页外,其他更屡次访问时候的请求阻塞问题;

(2)解决了除用户第一次访问网页外,其他访问的闪烁问题;

(3)减小了第一次请求页面的渲染时间;

(4)获得了在Google Page Speed Insights 和 WebPageTest.org 上更高的分数。

8. 看看实际效果

英文版本的做者说到本文缺乏一些细节的说明,可以在他博客中留言讨论。

英文版本的做者 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就行)。

gfonts-timeline

这个timeline说明在DOMContentLoaded事件以前,字体的加载已经开始了。

(5)若是上面的前面还不够糟糕,大多数浏览器将呈现空白文本,在不一样浏览器之间实际的行为会有所不一样:

A. 若是请求字体还不可用,IE 会当即使用后备字体呈现,并在字体下载完成以后立刻从新呈现;

B. Firefox 和 Chrome 35+ 会首先下载3秒钟的字体,若是超过3秒钟后,会使用后备字体渲染网页,等到指定字体下载完成后再从新渲染网页;

C. Safari 和 Chrome 35以前的版本,会等到指定字体下载完成后再渲染网页(PS:就是不会使用后备字体)。

注:以上说明中没有表示IE的版本以及Safari的版本号,因此须要本身测试才能算正确。

所以,若是网络链接缓慢,在大多数浏览器中将延迟超过3秒的文本渲染。在最坏的状况下,若是你的字体加载带有时间限制(因为一些链接很慢的移动设备),Safari 用户将不会再展现文本,剩下一个空白网页。若是网页请求超时,最终将只会呈现一个空白网页。

更多的信息能够访问:Ilya Gregorik's blog

其余相关资源:

其实英文版本的做者也是翻译的一篇俄文,这篇俄文来自于:

Russian by Максим Усачев

英文版本原文出自:

http://bdadam.com/blog/loading-webfonts-with-high-performance.html

注:若是你有兴趣能够再看一下英文版本和俄文版本文章下面的评论,里面还有一些颇有价值的东西,这里就再也不翻译了,有时间能够再整理一下。以上文章若是有翻译不恰当的地方请在文章后面留言,看见了必定回复而且修改。

原文出自:http://www.60sky.com

相关文章
相关标签/搜索