溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

CSS中如何優(yōu)化@font-face性能

發(fā)布時間:2021-06-11 14:06:09 來源:億速云 閱讀:261 作者:Leah 欄目:web開發(fā)

今天就跟大家聊聊有關(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所支持的字體可以有以下類型:

CSS中如何優(yōu)化@font-face性能

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)的字體,也會下載。

在其它瀏覽器中也不盡相同,

比如在 FirefoxIE 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è)資訊頻道,感謝大家的支持。

向AI問一下細(xì)節(jié)

免責(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)容。

AI