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