在現在化前端中使用特殊字型

carro發表於2018-11-19

需求導向

作為一個前端,肯定遇到過這個需求,UI做出來的設計稿利用了特殊字型。雖然對於前端來說,管你什麼字型,我微軟雅黑通吃,但是有時候UI會很執著,“這個一定要實現,你直接切一張圖片上去也行”。為了省事,我們肯定是直接切一張圖上去啊,但是每次切完圖之後,圖片都需要加工優化。每次替換文字都要重新編輯psd圖 -> 切圖 -> 優化圖片。所以還原高保真的時候要遵循一個原則,能用html實現的就不要用圖片代替,美言之為了效能,其實還是為了無止境的需求變更。

我們知道使用特殊字型,只要引入字型的ttf檔案(ttf檔案,這裡不做介紹,可自行百度)就行。如下:

@font-face {
  font-family: "fashion";
  src: url('./fashion.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}
.fashion-font {
  font-family: "fashion";
}
複製程式碼

但是字型檔案一般包含所有字型,字型檔案大小几M,對於前端來說,肯定是不能接受的,所以我們需要對ttf檔案進行打包操作,只引用用到的文字,這裡我們稱靜態文字,後面會介紹動態文字的解決方案。

font-spider

font-spider是一個npm庫,可以解析html用到特殊字型的文字,按需打包,替換原來的ttf檔案,並且在ttf檔案目錄下生成一個.font-spider資料夾存放原來總的ttf檔案。使用下面命令可進行打包操作:

sudo font-spider --debug src/**/index.html
複製程式碼

--debug命令可以檢視解析過程。

結合webpack

如果你是傳統的多頁面應用,這樣的打包方式是沒問題。但是現代前端工程化之後,前端只會有一個index.html入口檔案,且css檔案是通過js引入的,font-spider無法解析js裡的css檔案,所以那些引用font-family: "fashion";字型的文字都會失效。這裡提供兩個解決方案:

1.在html裡引入絕對路徑的css檔案,https://www.baidu.com/index.css

2.採用相對路徑,基於網站根目錄。一般情況下webpack工程下都會在專案根目錄下建一個static目錄存放靜態檔案。路徑如下:

<link rel="stylesheet" href="./static/mgday2018/font/font.css" type="text/css">
複製程式碼

這裡有一點需要注意,打包的時候,font-spider是根據index.html檢索css所對應的相對目錄,比如專案中有多個html檔案,所以他們所對應的字型檔案的位置需要根據html所在的位置。而且你使用字型的方式,不是在使用的地方上加font-family: "fashion";樣式,而是通過class的方式引入(如class="fashion-font"),這樣打包的時候才能被依賴。

  <link rel="stylesheet" href="./static/mgday2018/font/font.css" type="text/css">
  <!-- 下面的地址是為了相容font-spider的打包地址 -->
  <link rel="stylesheet" href="../../../static/mgday2018/font/font.css" type="text/css">
複製程式碼

最終實現效果

在現在化前端中使用特殊字型

動態文字

有些人會說你這是靜態文字啊,有些文字是通過後端介面返回的,我們無法提前打包啊。這裡提供三個解決方案:

1.利用fontmin.js

fontmin.js允許你提前將需要的問題,提前打包,即使文字不在html裡。但這其實這只是解決文字不在html裡,還是沒解決後端介面返回的文字的問題。參考連結: 移動端引入的字型檔案過大處理方法

2.實時打包

原理:搭建一個node中間層,每次介面返回的時候,先呼叫node服務fontmin,打包介面中用到的文字,然後返回一個靜態地址給前端,前端拿到介面資料和一個靜態css地址,先載入css地址,再載入文字。但是這會造成很大的資源浪費,且每次生成一個字型檔案。這裡再提供一種思路,node中間層每次獲取介面文字,重新編譯頁面中所有需要用到的文字(這裡會有快取對比,如果文字都已經包含,則不重新打包),再把css地址和資料返回給前端。但無論如何,只能針對幾個介面開放實時打包,否則再大的伺服器也抗不住這種壓力。

3.引入整個字型檔案

回到老問題,引入整個字型檔案。首屏所需要用到的字型檔案先單獨打包,先載入首屏需要用的字型檔案,再通過延遲載入和cdn,載入整個字型檔案。這樣能比較好的實現動態文字的問題。

總結

可見很明顯,動態的文字其實不適合特殊字型,無論怎麼優化,都會浪費很多資源,效能也是一個問題。所以我們只能期望將來某一天,網速飛快了,幾M的檔案能瞬間載入了,這個問題就迎刃而解了。


寫作時間:20181118

相關文章