1. 程式人生 > 其它 >前端網頁字型優化指南

前端網頁字型優化指南

日常開發網頁經常會使用一些特殊字型,比如思源黑體、蘋方字型等,因為這些字型在一般的宿主環境中是不存在的,需要通過 css 的 @font-face 定義,並從伺服器中載入對應的字型檔案,而字型檔案一般都是比較大的,甚至有時候一個字型比其他所有的資源(js、css、圖片)加起來還要大,對網頁的載入效能起到非常關鍵的影響,因此有必要對字型進行一些優化。 本文主要從字型格式、按需提取、統一渲染三個方面來談談優化字型的常用技巧。

轉換字型格式

現在是 1202 年了,各主流裝置基本都支援 woff2 字型格式,因此網站中沒有必要再引入多種不同格式的字型了。一般地,建議只引入 woff2 就好了,既可以保持程式碼的簡潔性,又可以減少上傳到你伺服器的檔案,何樂而不為?

可是很多時候美術同學只提供其他格式的字型檔案給我們,比如 TTF 或 OTF,那如何將其轉換成 woff2 呢?

  • TTF 字型轉 WOFF2

TTF 字型,是蘋果和 windows 都支援的一種字型,因此是美術同學最喜歡用的。TTF 轉換 WOFF2 是比較簡單的,可以選擇線上轉換,推薦的網站有以下兩個

但是個人覺得線上轉換等待上傳的時間比較久,而且有時候生成的檔案是空白的,因此更加傾向於使用 node 庫 ttf2woff2 轉換。該庫的周下載量達到 10w+ 的,可見好多人都會有將 tff 轉換成 woff2 的需求。
使用方法也很簡單:

cat font.ttf | ttf2woff2 > font.woff2

因為使用 了 cat 命令來提取 ttf 的內容,如果你使用的是 windows ,需要使用 git bash 或 wsl 來執行。

  • OTF 轉 WOFF2

除了 TTF ,美術同學還經常提供 OTF 給我們,這是微軟和 Adobe 共同研發的字型,因此在 windows 平臺還是比較流行的。那如何將其轉換成 WOFF2 呢?目前我還沒有發現哪個線上網站或 node 庫能一步到位轉換的,在 google 上搜索好幾個線上轉換的網站,要麼轉換完成後無法下載 ,要麼轉換下載後是個空檔案,反正就是不靠譜的東西。

經過一番折騰後,找到了一個不錯的 python 庫 otf2ttf,能夠穩定的將 otf 轉 ttf。
使用方法也比較簡單,首先安裝 python,然後通過 pip 安裝 otf2ttf 就可以使用了(pip 類似於 npm,是 python 的包管理器),不過官方的文件中示例程式碼應該是有一點小筆誤:

otf2ttf MyFont.ttf

裡面的 MyFont.ttf 應該是 MyFont.otf 才對,因為這個 input 應該是 OTF 型別而不是 TTF 。

使用 python otf2ttf 生成 ttf 檔案 後,就可以使用上面提到的將 ttf 轉換成 woff2 的方法獲取到 woff2 了。

關於字型轉換的這裡再囉嗦一下:有時候美術同學還會提供 ttc 檔案給我們,這不是單個字型,而是將多種字型打包在一起了,需要從中提取出 ttf 後才能使用,可以嘗試使用 TTC2TTF

按需壓縮字型

一般的,儘管將字型轉換成 woff2 格式,最小依然也有好幾百 K ,而更多情況下會有 1-4M 左右。有時候,我們只有少數的文字需要用到特殊字型,比如說只有 0-9 這 10 個數字用到某種特殊字型,如果把整個字型檔案引入就沒有必要了,比切10個圖片還要大。好在有一些技術能夠將 0-9 這10個數字對應的字型子集提取出來。我平時會使用 font-spider 字蜘 來提取。

首先,全域性安裝 font-spider:

npm install font-spider -g

然後,新建一個 html 檔案,比如檔名為 index.html ,裡面用一個元素包含所有的你想要提取的文字,比如 0-9,併為這個元素定義上你想要的特殊字型:

 <h1>0123456789</h1>


<style>
@font-face {
  font-family: 'sourceHan';
  src: url('./SourceHanSansCN-Regular.ttf');
  font-weight: normal;
  font-style: normal;
}


h1 {
    font-family: 'sourceHan';
}
</style>

最後,在這個 html 檔案所在的目錄執行以下命令:

font-spider index.html

這時候,原來的 SourceHanSansCN-Regular.ttf 就會被移動到 .font-spider/ 目錄下,而原來位置的字型會被替換成只提取了 0-9 的字型檔案。這個體積相差了好幾個數量級的:

完整的字型檔案大小是 10M :

只提取 0-9 10 個數字的字型檔案只有 7K:

所以,如果你的網站內容是靜態不變的,則建議使用 font-spider 將你所要用到的文字提取出來,這將會大大的減少字型檔案的體積。

統一渲染時機

將字型轉換成 WOFF2 及靜態內容網站使用 font-spider 進行按需壓縮,可以很好的控制字型的大小。(PS:WOFF2 字型沒有必要再開啟 GZIP,因為這個字型文字本身就是壓縮過的)。

最後,我們再來看看網路速度對字型內容的影響,假如你的網頁全部內容都使用某種字型,CSS 定義如下:

@font-face {
  font-family: myfont;
  src: url('./myfont.woff2') format('woff2');
}


body {
  font-family: myfont;
}

假如這個 myfont.woff2 檔案大小為 4M,而網路下載速度只有 1M/s ,則載入這個字型需要 4 秒鐘。這4秒期間由於還沒有載入完成遠端字型,瀏覽器會使用什麼字型渲染呢?事實上,不同的瀏覽器表現會不一樣的,以下是一些常見的桌面瀏覽器的表現:

  • IE:它會直接使用備用字型渲染,最後等webfont字型載入完畢後重新渲染。

  • Safari:它會一直等待webfont字型載入完畢,並且期間不會渲染字型。

  • Chrome / Firefox:它們會等待webfont字型載入,如果在3秒之內沒有載入完畢,則使用備用字型渲染。最後webfont載入完畢,使用並重新渲染。

我們需要想辦法統一這些行為,比較理想的行為是:先使用系統預設字型,等到遠端字型載入完成了再替換成特殊字型。藉助於 WebFontLoader 可以很容易的實現這一效果。下面來看一下如何使用:

  1. 在 css 中通過 @font-face 定義一個字型:
@font-face {
  font-family: 'myfont';
  src: url('./myfont.woff2') format('woff2');
}

注意,CSS 中只需要定義字型就行,而不要使用使用這個字休。

  1. 然後 引入 webfontloader (也可以通過 npm 安裝),將你要使用的字型新增到 custom.families 列表中,並在 active 回撥中將該字型新增到對應的元素上,程式碼如下:
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
WebFont.load({
custom:{
families:['myfont'],
},
classes:false,
active(){
document.body.style.fontFamily='myfont';
},
});
</script>

這樣瀏覽器一開始就會使用預設字型渲染內容,等字型載入完成後再使用特殊字型重新渲染。

小結

關於字型優化技巧就先寫到這裡啦,有問題的歡迎留言交流哈。