您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關CSS中如何優化@font-face性能,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
一、 font-face基本用法
font-face的基本用法想必大家都是知道的,基本上就是類似這樣:
@font-face { font-family: Lato; src: url('font-lato/lato-regular-webfont.woff2') format('woff2'), url('font-lato/lato-regular-webfont.woff') format('woff'), url(font-lato/lato-regular-webfont.ttf) format("opentype"); } p { font-family: Lato, serif; }
這樣就可以使我們的網頁用上自定義字體了。 除了font-family 和 src屬性之外,還擁有font-style以及font-weight屬性。 src可以指定多種字體,會按順序依次適用,比如上面的示例中會先加載woff2字體,如果失敗再加載woff字體,否則加載opentype字體。 src所支持的字體可以有以下類型:
src參數帶不帶引號都可以,參數的格式不同含義也不盡相同,比如下面:
src: url(fonts/simple.woff); /* 加載simple.woff,地址相對于樣式表的地址 */ src: url(/fonts/simple.woff); /* 加載simple.woff,地址是網站的絕對地址 */ src: url(fonts/coll.otc#foo); /* 從coll.otc字符集中加載foo字體 */ src: url(fonts/coll.woff2#foo); /* 從coll.woff2字符集中加載foo字體 */ src: url(fonts.svg#simple); /* 加載id 為'simple'的SVG字體 */
src中加載的字體地址受跨域的約束,如果想跨域加載字體,需要設置CORS。
這就是font-face的最基礎的用法。 接下來我們會進一步分析font-face的用法,并盡可能的找出優化策略。
二、 什么時候會下載字體?
上面講了字體的基本知識,那你有沒有想過,字體是在什么時候下載的呢?當我們僅僅在CSS中定義如下樣式的時候, 頁面加載,字體會自動下載嗎?
@font-face { font-family: Lato; src: url('font-lato/lato-regular-webfont.woff2') format('woff2'), url('font-lato/lato-regular-webfont.woff') format('woff'), url(font-lato/lato-regular-webfont.ttf) format("opentype"); }
很遺憾,字體并不會下載。 通常情況 下,只有當我們的頁面元素用到了font-face中定義的字體的情況下,才會下載對應的字體。
注意: 這里我們說了是通常情況,這是因為,IE8在只要是定義了font-face,即使頁面元素沒有使用對應的字體,也會下載。
在其它瀏覽器中也不盡相同,
比如在 Firefox 和 IE 9+ 中,遇到如下情況也會下載字體:
html
<div id="test"></div>
css
#test { font-family: Lato; }
有什么特別之處呢? 你可能注意到了,這個元素雖然使用到了font-family: Lato樣式,但是這個元素并沒有任何文本啊!!!。 按照我們的理想情況,應該是,只有有文字內容才會去下載字體嘛。 而這就是Chrome, Safari (WebKit/Blink 等)瀏覽器的行為。
Chrome, Safari (WebKit/Blink 等)瀏覽器只有在如下類似情況才會去下載字體:
html
<div id="test">這里是有文本的哦</div>
css
#test { font-family: Lato; }
所以總結一下,不同瀏覽器下載字體的策略:
IE8 只要定義了font-face,就會去下載字體,不論實際有沒有應用該字體。
Firefox, IE 9+ 只有定義了font-face 并且頁面有元素應用了該字體,就會去下載,不論該元素是否有文本內容。
Chrome, Safari 只有定義了font-face 并且頁面有元素應用了該字體,并且該元素有文本內容,才會去下載字體。
那你可能會問了,如果我們的DOM元素是通過動態插入的呢?比如:
var el = document.createElement('div'); el.style.fontFamily = 'open_sansregular'; document.body.appendChild(el); el.innerHTML = 'Content.';
答案是一樣的,它的下載策略如下:
var el = document.createElement('div'); el.style.fontFamily = 'open_sansregular'; /* 到這里,IE8就會開始下載字體 */ document.body.appendChild(el); /* 只有到這里,Firefox, IE 9+ 才會開始下載字體 */ el.innerHTML = 'Content.'; /* 只有到這里,Chrome, Safari 才會開始下載字體 */
三、 FOIT(Flash of Invisible Text)
FOIT是瀏覽器在加載字體的時候的默認表現形式,也就是在字體加載過程中,頁面是看不到文本內容的。在現代瀏覽器中,FOIT會導致這種現象出現至多3秒。FOIT會導致很差的用戶體驗,這是我們需要盡量去避免的。
四、 FOUT(Flash of Unstyled Text) 與 font-display屬性
FOUT意思是在字體加載過程中使用默認的系統字體,字體加載完后顯示加載的字體,如果超過了FOIT(3s)字體還沒加載,則繼續使用默認的系統字體。
IE瀏覽器和Edge不會等待FOIT超時才顯示默認字體,會立即顯示默認字體。FOUT比FOIT好,但是需要注意它引起的reflow.
那么要想使瀏覽器有FOUT行為,我們需要在設置@font-face的時候給它加一個屬性:font-display。 font-display默認是auto, 可選屬性與含義如下:
auto. The font display policy is user-agent-defined.
block. Gives the font face a short block period (3s is recommended in most cases) and an infinite swap period.
swap. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and an infinite swap period.
fallback. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a short swap period (3s is recommended in most cases).
optional. Gives the font face an extremely small block period (100ms or less is recommended in most cases) and a 0s swap period.
一般設置成fallback和optional即可。
五、 preload
在頁面加入下面這個代碼以便更快的加載字體:
<link rel="preload" href="font.woff2" as="font" type="font/woff2" crossorigin>
通常和最基本的字體用法配合使用
六、 字體轉 BASE64URI
這種方法就是將@font-face中定義字體時的路徑直接改為字體的base64編碼。
優點: 這種做法的優點是不會產生FOIT和FOUT。所以也不會有reflow和repaint. 缺點: 字體轉成base64也會很大,會影響頁面首次加載速度。不支持逗號分隔的形式加載多種格式的字體,只能加載一種格式字體。這導致你為了盡可能保證所有瀏覽器都可以兼容,通常會指定為woff格式,因為woff格式兼容性好,但是卻沒法使用更小體積的woff2格式,因為woff2格式兼容性差點。
七、異步加載BASE64格式URI字體
這種方法就是通過異步的方式插入帶有BASE64格式URI字體的CSS鏈接。
八、使用Font Load API + FOUT + class切換
這種方式是期初并不使用用到@font-face的class,然后用Font Load API加載我們想用的字體,然后切換相應的CSS即可。Font Load API是原生的API:
document.fonts.load('1em open_sansregular') .then(function() { var docEl = document.documentElement; docEl.className += ' open-sans-loaded'; }); .open-sans-loaded h2 { font-family: open_sansregular; }
當然這種方法需要考慮瀏覽器兼容性的問題。
九、 FOFT(Flash of Faux Text)
FOFT會把字體的加載分成多個部分,首先加載羅馬網絡字體,然后會在加載真實的粗體和斜體的時候立即使用font-synthesis屬性渲染粗體和斜體的變體。
這種方法是基于[ 使用Font Load API + FOUT + class切換
]這種方式的,非常適合加載同一種字體但是不同粗細,字形的場景,比如羅馬、粗體、斜體、粗斜體等。我們將這些字體分成2階段: 第一階段是羅馬字體,然后立即渲染人造粗體和斜體,最后(第二階段)用真實字體替代。這里面還可以使用sessionStorage優化訪問重復視圖的場景。
十、CRITICAL FOFT
CRITICAL FOFT和標準的FOFI的唯一區別就在于第一階段羅馬字體的加載,CRITICAL FOFT不會加載羅馬字體的全集,只會加載它的一個子集(比如A-Za-z0-9),全集會在第二階段加載。
十一、CRITICAL FOFT WITH DATA URI
這個和CRITICAL FOFT的唯一區別就是羅馬子集字體的加載方式,前面是用Font Load API完成了,這里會將馬子集字體硬編碼成BASE64 URI的形式加載。
看完上述內容,你們對CSS中如何優化@font-face性能有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。