Web 性能優化:使用 CSS font-display 控制字體加載和替換


在編寫網站的時候,或多或少都會用到一些網絡上的字體,CSS 3 中雖然加入了對 Web Fonts(網絡字體)的支持,但是瀏覽器對它們的加載和默認處理方式會極大的影響網站的性能和用戶體驗。例如默認情況下,在 Web Fonts 加載時,使用該字體的地方會顯示空白,直到字體下載完成之后才會顯示,這時通過改變 CSS 中的 font-display 屬性,就可以避免這個問題。

什么是 Web Fonts

在介紹 font-display 之前,先了解一下什么是 Web Fonts。在以前使用 CSS 指定字體時只能使用用戶電腦本地上現有的字體,而由於每個用戶電腦上的字體可能都不一樣,所以能用的基本上就是操作系統內置的一些字體,例如微軟雅黑,宋體,蘋果蘋方,這些也叫做安全字體(Web Safe Fonts)。為了使字體顯示正常,我們一般會通過 font-family 屬性同時指定多個字體,如果第一個字體沒有在操作系統中找到,就會使用下一個后備字體( Fallback Font ),以此類推:

* {
  font-family: "PingFang SC", "Microsoft Yahei", sans-serif;
}

 

后來,CSS 開始支持 @font-face 這個指令,可以加載自定義的字體文件,這個時候可以把字體隨網站一起發布,用戶在瀏覽網站的時候,會下載 @font-face 中指定的字體。例如下邊的代碼加載了 fonts 目錄下的 Raleway 字體:

@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-weight: 500;
  src: url(/fonts/raleway.woff2) format('woff2');
}

 

src 屬性用於指定字體的位置,其中 url() 函數也接受網絡地址,來加載第三方提供的字體文件,這樣也催生了像 Google Fonts 這樣的雲字體服務。不過,基本上只有英文字體才適合 Web Fonts,因為它只有 26 個英文字母外加數字,體積小,適合在網絡上傳輸,而中文光常用的就有 3000 個字符,所以一般只使用操作系統自帶的,不過現在也有字體服務會根據網站上所使用的文字去動態的生成字體文件。

瀏覽器加載 Web Fonts 的時期

瀏覽器加載 Web Fonts 時按順序會有三個時期:

阻塞期(Block Period)。在此期間如果字體沒有加載完成,那么瀏覽器會使用 font-family 指定的字體列表中的后備字體(Fallback)進行渲染,但是顯示為空白,也就是對於用戶是不可見的。在此期間字體加載完成之后才能正常顯示該字體。

交換期(Swap Period)。跟阻塞期類似,但是在這個時期內,它會在字體加載時,先用后備字體渲染文本並顯示出來(而不是顯示空白),在此期間字體加載完成之后才能正常的顯示該字體。

失敗期(Failure Period)。如果字體加載失敗,則使用后備字體顯示文本。

 

 

 

至於每個時期有多長,是根據 font-display 屬性的值來確定的。

font-display 介紹

font-display 確切的說不是 CSS 屬性,而是專用於 @font-face 指令的描述符,它可以取如下幾個值:

auto 。這個是 font-display 的默認值,字體的加載過程由瀏覽器自行決定,不過基本上和取值為 block 時的處理方式一致。

block 。在字體加載前,會使用備用字體渲染,但是顯示為空白,使得它一直處於阻塞期,當字體加載完成之后,進入交換期,用下載下來的字體進行文本渲染。不過有些瀏覽器並不會無限的處於阻塞期,會有超時限制,一般在 3 秒后,如果阻塞期仍然沒有加載完字體,那么直接就進入交換期,顯示后備字體(而非空白),等字體下載完成之后直接替換。

swap 。基本上沒有阻塞期,直接進入交換期,使用后備字體渲染文本,等用到的字體加載完成之后替換掉后備字體。

fallback 。阻塞期很短(大約100毫秒),也就是說會有大約 100 毫秒的顯示空白的后備字體,然后交換期也有時限(大約 3 秒),在這段時間內如果字體加載成功了就會替換成該字體,如果沒有加載成功那么后續會一直使用后備字體渲染文本。

optional 。與 fallback 的阻塞期一致,但是沒有交換期,如果在阻塞期的 100 毫秒內字體加載完成,那么會使用該字體,否則直接使用后備字體。這個就是說指定的網絡字體是可有可無的,如果加載很快那么可以顯示,加載稍微慢一點就不會顯示了,適合網絡情況不好的時候,例如移動網絡。

那么在了解 font-display 之后,那么我們應該不難看出來,對於大部分情況應該把它的值設置為 swap ,這樣在加載網絡字體期間,使用后備字體進行渲染,加載完成之后在替換為指定的網絡字體。

 

 

 

應用

現在使用谷歌的 Web Fonts 字體服務已經不需要我們用手動去寫 @font-face 指令了,而是通過調用它的接口,直接返回一段 @font-face 指令 CSS 代碼,同時它也支持 display=swap 參數,來讓返回的 CSS 代碼中,設置 font-display 為 swap ,這個可以從我的網站上看到:

/* https://fonts.font.im/css?family=Raleway:500,700&display=swap */
@font-face {
  font-family: 'Raleway';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(https://fonts.gstatic.font.im/s/raleway/v19/1Ptug8zYS_SKggPNyCAIT4ttDfCmxA.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* ... */

 

瀏覽器支持

從 caniuse.com 網站上可以查到,這個屬性在各個瀏覽器中的支持程度為(最低版本):

 

 

 

關於本文

作者:@峰華
原文:https://zxuqian.cn/css-font-display-intro/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM