在先前的單元中,您已瞭解如何最佳化 HTML、CSS、JavaScript 和媒體資源。在本單元中,您將瞭解幾種最佳化網頁字體的方法。
網頁字型可能會影響網頁在載入和算繪時的效能。
大型字型檔案可能需要一段時間才能下載完成,並對首次內容繪製 (FCP) 造成負面影響,而錯誤的 font-display
值可能會導致不必要的版面配置位移,進而影響網頁的累計版面配置位移 (CLS)。
在討論如何最佳化網頁字型之前,瞭解瀏覽器如何探索網頁字型很有幫助,這樣您就能瞭解 CSS 如何在特定情況下防止擷取不必要的網頁字型。
探索
網頁的網頁字型是在樣式表中使用 @font-face
宣告定義:
@font-face {
font-family: "Open Sans";
src: url("/fonts/OpenSans-Regular-webfont.woff2") format("woff2");
}
上述程式碼片段定義了名為 "Open Sans"
的 font-family
,並告知瀏覽器要在何處尋找相應的網路字型資源。為節省頻寬,瀏覽器會先判斷目前網頁的版面配置是否需要網路字型,再下載該字型。
h1 {
font-family: "Open Sans";
}
在上述 CSS 程式碼片段中,瀏覽器會在剖析網頁 HTML 中的 <h1>
元素時,下載 "Open Sans"
字型檔案。
preload
如果 @font-face
宣告是在外部樣式表定義,瀏覽器必須先下載樣式表,才能開始下載這些宣告。因此網頁字型屬於延遲探索的資源,但您可以採取一些方法,協助瀏覽器更快探索網頁字型。
您可以使用 preload
指令,提早要求網頁字型資源。preload
指令可讓網頁字型在網頁載入期間及早被探索,瀏覽器會立即開始下載這些字型,不必等待樣式表下載及剖析完畢。preload
指令不會等到網頁需要字型時才載入。
<!-- The `crossorigin` attribute is required for fonts—even
self-hosted ones, as fonts are considered CORS resources. -->
<link rel="preload" as="font" href="/fonts/OpenSans-Regular-webfont.woff2" crossorigin>
內嵌@font-face
聲明
您可以使用 <style>
元素,在 HTML 的 <head>
中內嵌轉譯阻斷 CSS (包括 @font-face
宣告),在網頁載入期間更早探索字型。在這種情況下,瀏覽器會在網頁載入時更早發現網頁字型,因為不需要等待下載外部樣式表。
內嵌 @font-face
宣告比使用 preload
提示更具優勢,因為瀏覽器只會下載顯示目前網頁所需的字型。這樣就能避免下載未使用的字型。
下載
瀏覽器發現網頁字型並確認目前頁面版面配置需要這些字型後,即可下載。網頁字型數量、編碼和檔案大小,都會顯著影響瀏覽器下載及算繪網頁字型的速度。
自行託管網頁字型
網頁字型可透過第三方服務 (例如 Google Fonts) 提供,也可以自行代管於來源。使用第三方服務時,網頁必須先開啟與供應商網域的連線,才能開始下載所需的網頁字型。這可能會延遲網頁字型的探索和後續下載作業。
使用 preconnect
資源提示可減少這項額外負荷。使用 preconnect
,您可以指示瀏覽器比平常更早開啟跨來源的連線:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
上述 HTML 片段會提示瀏覽器建立與 fonts.googleapis.com
的連線,以及與 fonts.gstatic.com
的 CORS 連線。部分字型供應商 (例如 Google Fonts) 會從不同來源提供 CSS 和字型資源。
您可以自行代管網路字型,省去第三方連線的麻煩。在大多數情況下,自行代管網頁字型會比從跨來源下載字型更快。如果您打算自行代管網頁字型,請確認網站使用內容傳遞聯播網 (CDN)、HTTP/2 或 HTTP/3,並為網站所需的網頁字型設定正確的快取標頭。
使用 WOFF2,且只能使用 WOFF2
WOFF2 獲得廣泛的瀏覽器支援,且壓縮效果最佳,比 WOFF 壓縮率高出 30%。檔案縮小後,下載速度會更快。WOFF2 格式通常是唯一需要的格式,可確保與新版瀏覽器完全相容。
建立網頁字型子集
網頁字型通常包含各種不同的字形,可呈現不同語言使用的各種字元。如果網頁只提供一種語言的內容,或使用單一字母,您可以透過子集化減少網頁字型的大小。通常是指定一或多個 Unicode 碼位。
子集是原始網頁字型檔案中包含的字形縮減集。舉例來說,網頁可能會提供拉丁字元的特定子集,而不是提供所有字形。視需要的子集而定,移除字形可大幅縮減字型檔案大小。
部分網頁字型供應商 (例如 Google 字型) 會透過查詢字串參數自動提供子集。舉例來說,https://fonts.googleapis.com/css?family=Roboto&subset=latin
網址會提供含有 Roboto 網頁字型的樣式表,但只使用拉丁字母。
如果您決定自行代管網頁字型,下一步就是使用 glyphanger 或 subfont 等工具,自行產生並代管這些子集。
不過,如果您無法自行代管網路字型,可以指定額外的text
查詢字串參數,只包含網站所需的 Unicode 碼位,藉此建立 Google Fonts 提供的網路字型子集。舉例來說,如果網站上的顯示網頁字型只需要「歡迎」一詞的少量字元,您可以透過下列網址,透過 Google Fonts 要求該子集:https://fonts.googleapis.com/css?family=Monoton&text=Welcome
。如果網站上需要使用這種極端子集,就能大幅減少網站上單一字體所需的網頁字型資料量。
字型顯示
瀏覽器探索並下載網頁字型後,即可進行算繪。根據預設,瀏覽器會封鎖使用網頁字型的文字轉譯作業,直到網頁字型下載完成為止。你可以使用 font-display
CSS 屬性調整瀏覽器的文字算繪行為,並設定在網頁字型完全載入前要顯示或隱藏的文字。
block
font-display
的預設值為 block
。使用 block
時,瀏覽器會封鎖任何使用指定網路字型的文字轉譯作業。不同瀏覽器的行為稍有不同。Chromium 和 Firefox 會先封鎖最多 3 秒的算繪作業,然後再使用備援字型。Safari 會無限期封鎖,直到網頁字型載入完畢為止。
swap
swap
是最廣為使用的 font-display
值。swap
不會封鎖算繪作業,並會在換入指定的網頁字型前,立即在備用字型中顯示文字。這樣一來,您就能立即顯示內容,不必等待網頁字型下載完成。
不過,如果備用網路字型和 CSS 中指定的網路字型在行高、字距和其他字型指標方面差異很大,swap
的缺點是會導致版面配置位移。如果您未注意使用 preload
提示盡快載入網頁字型資源,或未考慮其他 font-display
值,可能會影響網站的 CLS。
fallback
font-display
的 fallback
值是 block
和 swap
之間的折衷方案。與 swap
不同,瀏覽器會封鎖字型的算繪作業,但只會在很短的時間內換入備用文字。不過,與 block
不同的是,封鎖期極短。
在網路速度快的環境中,使用 fallback
值效果良好,因為網頁字型下載速度快,網頁初始算繪時會立即使用網頁字型。不過,如果網路速度緩慢,系統會在封鎖期結束後先顯示備用文字,然後在網頁字型載入後替換。
optional
optional
是最嚴格的 font-display
值,只有在網頁字型資源於 100 毫秒內下載完畢時,才會使用該資源。如果網頁字型載入時間超過這個值,網頁就不會使用該字型,瀏覽器會使用目前導覽的備用字體,同時在背景下載網頁字型並放入瀏覽器快取。
因此,後續的網頁瀏覽作業可以立即使用網頁字型,因為系統已下載該字型。font-display: optional
可避免 swap
造成的版面配置位移,但如果網頁字型在初始網頁導覽中載入時間過晚,部分使用者就看不到。
字型範例
學以致用
瀏覽器何時會下載網頁字型資源 (假設不是使用 preload
指令擷取)?
如要向所有新式瀏覽器提供網頁字型,唯一 (也是最有效率) 的必要格式為何?
下一步:程式碼分割 JavaScript
瞭解字型最佳化後,您現在可以前往下一個單元,瞭解如何透過程式碼分割延遲載入 JavaScript,這項主題有助於大幅提升使用者初始網頁載入速度。這樣做可盡量減少網頁啟動階段的頻寬和 CPU 爭用情形,因為使用者很可能會在這段時間與網頁互動。