在響應式網站中,提高加載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

相關文章
相關標籤/搜索