平常開發網頁常常會使用一些特殊字體,好比思源黑體、蘋方字體等,由於這些字體在通常的宿主環境中是不存在的,須要經過 css 的 @font-face
定義,並從服務器中加載對應的字體文件,而字體文件通常都是比較大的,甚至有時候一個字體比其餘全部的資源(js、css、圖片)加起來還要大,對網頁的加載性能起到很是關鍵的影響,所以有必要對字體進行一些優化。 本文主要從字體格式、按需提取、統一渲染三個方面來談談優化字體的經常使用技巧。javascript
如今是 1202 年了,各主流設備基本都支持 woff2 字體格式,所以網站中沒有必要再引入多種不一樣格式的字體了。通常地,建議只引入 woff2 就行了,既能夠保持代碼的簡潔性,又能夠減小上傳到你服務器的文件,何樂而不爲?css
但是不少時候美術同窗只提供其餘格式的字體文件給咱們,好比 TTF 或 OTF,那如何將其轉換成 woff2 呢?html
TTF 字體,是蘋果和 windows 都支持的一種字體,所以是美術同窗最喜歡用的。TTF 轉換 WOFF2 是比較簡單的,能夠選擇線上轉換,推薦的網站有如下兩個java
可是我的以爲線上轉換等待上傳的時間比較久,並且有時候生成的文件是空白的,所以更加傾向於使用 node 庫 ttf2woff2 轉換。該庫的周下載量達到 10w+ 的,可見好多人都會有將 tff 轉換成 woff2 的需求。 使用方法也很簡單:node
cat font.ttf | ttf2woff2 > font.woff2
複製代碼
由於使用 了 cat 命令來提取 ttf 的內容,若是你使用的是 windows ,須要使用 git bash 或 wsl 來運行。python
除了 TTF ,美術同窗還常常提供 OTF 給咱們,這是微軟和 Adobe 共同研發的字體,所以在 windows 平臺仍是比較流行的。那如何將其轉換成 WOFF2 呢?目前我尚未發現哪一個線上網站或 node 庫能一步到位轉換的,在 google 上搜索好幾個線上轉換的網站,要麼轉換完成後沒法下載 ,要麼轉換下載後是個空文件,反正就是不靠譜的東西。git
通過一番折騰後,找到了一個不錯的 python 庫 otf2ttf,可以穩定的將 otf 轉 ttf。 使用方法也比較簡單,首先安裝 python,而後經過 pip 安裝 otf2ttf 就可使用了(pip 相似於 npm,是 python 的包管理器),不過官方的文檔中示例代碼應該是有一點小筆誤:github
otf2ttf MyFont.ttf
複製代碼
裏面的 MyFont.ttf 應該是 MyFont.otf 纔對,由於這個 input 應該是 OTF 類型而不是 TTF 。web
使用 python otf2ttf 生成 ttf 文件 後,就可使用上面提到的將 ttf 轉換成 woff2 的方法獲取到 woff2 了。ajax
關於字體轉換的這裏再囉嗦一下:有時候美術同窗還會提供 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 能夠很容易的實現這一效果。下面來看一下如何使用:
@font-face {
font-family: 'myfont';
src: url('./myfont.woff2') format('woff2');
}
複製代碼
注意,CSS 中只須要定義字體就行,而不要使用使用這個字休。
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>
複製代碼
這樣瀏覽器一開始就會使用默認字體渲染內容,等字體加載完成後再使用特殊字體從新渲染。
關於字體優化技巧就先寫到這裏啦,有問題的歡迎留言交流哈。