一種減少字體加載影響的新方法:CSS 字體描述符
已發表: 2022-03-10字體加載長期以來一直是 Web 性能的問題,這裡確實沒有好的選擇。 如果您想使用網絡字體,您的選擇基本上是 Flash of Invisible Text (aka FOIT),其中文本在字體下載之前一直隱藏,或 Flash of Unstyled Text (FOUT),您最初使用後備系統字體,然後將其升級到下載時的網絡字體。 說實話,這兩種選擇都沒有真正“獲勝”,因為兩者都不是真正令人滿意的。
font-display
不應該解決這個問題嗎?
@font-face
的font-display
屬性為 Web 開發人員提供了這個選擇,而之前瀏覽器決定這樣做(過去 IE 和 Edge 偏愛 FOUT,而其他瀏覽器偏愛 FOIT)。 然而,除此之外,它並沒有真正解決問題。
許多網站在第一次出現時轉移到font-display: swap
,Google Fonts 甚至在 2019 年將其設為默認值。這裡的想法是盡可能快地顯示文本對性能更好,即使它在後備字體中,然後在最終下載時交換字體。
那時我也支持這一點,但是當網絡字體下載和字符因字體之間的差異而擴展(或收縮)時,我越來越發現自己對“水合效應”感到沮喪。 與大多數出版商一樣,Smashing Magazine 使用網絡字體,下面的屏幕截圖顯示了初始渲染(使用後備字體)和最終渲染(使用網絡字體)之間的區別:
現在,當並排放置時,網絡字體要好得多,並且適合 Smashing Magazine 品牌。 但是我們也看到這兩種字體的文本佈局有很大的不同。 字體的大小非常不同,因此,屏幕內容會發生變化。 在這個 Core Web Vitals 和 Cumulative Layout Shifts 被(非常正確地!)認為對用戶有害的時代, font-display: swap
是一個糟糕的選擇,因此。
我已經恢復到font-display: block
在我照顧的網站上,因為我確實發現文本移動非常刺耳和煩人。 雖然block
確實不會停止移位(字體仍然呈現在不可見的文本中),但它至少使它們對用戶不那麼明顯。 我還通過預加載我通過自託管子集字體盡可能小的字體來優化字體加載——因此訪問者經常會在很短的時間內看到後備字體。 對我來說, swap
的“阻塞期”太短了,老實說,我寧願多等一會兒才能讓初始渲染正確。
使用font-display: optional
可以解決 FOIT 和 FOUT — 有代價
另一種選擇是使用font-display: optional
。 這個選項基本上使網絡字體成為可選的,或者換句話說,如果在頁面需要它的時候字體不存在,那麼瀏覽器永遠不會交換它。 有了這個選項,我們基本上只使用已經下載的字體來避免 FOIT 和 FOUT 。
如果 web 字體不可用,我們會回退到備用字體,但下一頁導航(或重新加載此頁面)將使用該字體 - 因為它應該已經完成下載。 但是,如果 Web 字體對網站來說並不重要,那麼完全刪除它可能是個好主意——這對 Web 性能甚至更好!
第一印像很重要,並且完全沒有網絡字體的初始加載似乎有點太多了。 我也認為——順便說一句,絕對沒有證據支持這一點! ——它會給人們一種印象,也許是潛意識的,網站有些“不對勁”,可能會影響人們使用網站的方式。
因此,所有字體選項都有其缺點,包括根本不使用網絡字體或使用系統字體的選項(這是有限制的——但可能不像許多人想像的那樣有限制!)。
使您的後備字體更接近您的字體
Web 字體加載的聖杯是使後備字體更接近實際的 Web 字體,以盡可能減少明顯的偏移,從而減少使用swap
的影響。 雖然我們永遠無法完全避免這種轉變,但我們可以做得比上面的截圖更好。 Monica Dinculescu 的 Font Style Matcher 應用程序經常在字體加載文章中被引用,並讓我們對這裡應該做的事情有了一個奇妙的一瞥。 它有助於您以兩種不同的字體覆蓋相同的文本以查看它們的不同之處,並調整字體設置以使它們更緊密地對齊:
不幸的是,字體樣式匹配的問題是我們不能讓這些 CSS 樣式只應用於後備字體,所以我們需要使用 JavaScript 和 FontFace.load API 來應用(或恢復)這些樣式差異。字體加載。
代碼量不是很大,但感覺還是比應該做的要多一些努力。 儘管正如 Zach Leatherman 在 2019 年的精彩演講中所解釋的那樣,為此使用 JavaScript API 還有其他優勢和可能性——您可以減少回流並處理data-server
模式,並且prefers-reduced-motion
(但請注意自從那次談話以來,兩人都接觸過 CSS)。
處理我們已經擁有的緩存字體也更棘手,更不用說各種備用樣式的差異了。 在 Smashing Magazine 上,我們嘗試了許多後備方案,以充分利用不同用戶和操作系統已安裝的系統字體:
font-family: Mija,-apple-system,Arial,BlinkMacSystemFont,roboto slab,droid serif,segoe ui,Ubuntu,Cantarell,Georgia,serif;
知道使用哪種字體,或者對每種字體進行單獨調整併確保正確應用它們很快就會變得非常複雜。
更好的解決方案即將到來
所以,這是對今天情況的簡要追趕。 然而,地平線上開始出現一些煙霧。
對字體的 CSS“大小調整”描述符感到興奮:通過字形的比例因子(百分比)匹配後備字體和主要 Web 字體來減少佈局變化。
— Addy Osmani (@addyosmani) 2021 年 5 月 22 日
請參閱@cramforce 的 https://t.co/mdRW2BMg6A 進行演示(Chrome Canary/FF Nightly with flags)pic.twitter.com/hEg1HfUJlT
正如我之前提到的,應用後備樣式差異的主要問題是添加,然後刪除它們。 如果我們可以告訴瀏覽器這些差異僅適用於後備字體怎麼辦?
這正是作為 CSS 字體模塊第 5 級的一部分提出的一組新字體描述符所做的。 這些應用於定義單個字體的@font-face
聲明。
Simon Hearne 寫了關於字體描述規範的提議更新,其中包括四個新的描述: ascent-override
、 descent-override
、 line-gap-override
和advance-override
(自從放棄)。 您可以使用 Simon 創建的 F-mods Playground 來加載您的自定義和備用字體,然後使用覆蓋來獲得完美匹配。
正如 Simon 所寫,這四個描述符的組合允許我們覆蓋後備字體的佈局以匹配 Web 字體,但它們只真正修改了垂直間距和定位。 所以對於字符和字母間距,我們需要提供額外的 CSS。
但事情似乎又在發生變化。 最近, advance-override
被放棄,取而代之的是即將推出的size-adjust
描述符,它允許我們通過字形的比例因子(百分比)匹配後備字體和主要 Web 字體來減少佈局變化。
它是如何工作的? 假設您有以下 CSS:
@font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } h1 { font-family: Lato, Arial, sans-serif; }
然後你要做的是為 Arial 後備字體創建一個@font-face
並將調整器描述符應用於它。 然後,您將獲得以下 CSS 片段:
@font-face { font-family: 'Lato'; src: url('/static/fonts/Lato.woff2') format('woff2'); font-weight: 400; } @font-face { font-family: "Lato-fallback"; size-adjust: 97.38%; ascent-override: 99%; src: local("Arial"); } h1 { font-family: Lato, Lato-fallback, sans-serif; }
這意味著當最初使用Lato-fallback
時(因為 Arial 是一種local
字體,無需任何額外下載即可立即使用),然後size-adjust
和ascent-override
設置允許您將其更接近 Lato 字體。 這是一個額外的@font-face
聲明,但肯定比我們之前必須跳過的那些箍要容易得多!
總的來說,本規範中包含四個主要@font-face
描述符: size-adjust
、 ascent-override
、 descent-override
和line-gap-override
,還有一些其他的仍在考慮用於下標、上標和其他用例.
Malte Ubl 創建了一個非常有用的工具,可以在給定兩種字體和支持這些新設置的瀏覽器的情況下自動計算這些設置(稍後會詳細介紹!)。 正如 Malte 指出的那樣,計算機擅長這類事情! 理想情況下,我們還可以向 Web 開發人員公開這些常用字體的設置,例如,也許在 Google 字體之類的字體集合中提供這些提示? 這肯定有助於提高采用率。
現在不同的操作系統可能會有稍微不同的字體設置,而將這些設置完全正確基本上是一項不可能完成的任務,但這不是目標。 目的是縮小差距,因此使用font-display: swap
不再是一種不和諧的體驗,但我們不需要走到optional
或沒有網絡字體的極端。
我們什麼時候可以開始使用它?
自版本 87 以來,其中三個設置已在 Chrome 中提供,儘管密鑰size-adjust
描述符尚未在任何穩定的瀏覽器中可用。 然而,Chrome Canary 和 Firefox 都有它,所以這不是一個抽象的、遙遠的概念,而是很快就會落地的東西。
目前,該規範有各種免責聲明和警告,表明它還沒有為實時做好準備,但它確實感覺它已經到了那裡。 與往常一樣,我們、設計師和開發人員之間存在平衡,測試並提供反饋,並阻止使用它,因此實施不會因為太多人最終使用較早的草案而陷入困境。
Chrome 已經表示他們打算在 7 月 20 日發布的 Chrome 92 中提供size-adjust
功能,這大概表明它幾乎就在那裡。
所以,還沒有完全準備好,但看起來它會在不久的將來出現。 同時,試玩一下 Chrome Canary 中的演示,看看它是否可以更接近解決您的字體加載問題以及它們造成的 CLS 影響。