Web Performance

Web fonts 仍是多數網站最容易拿下的效能收益

Variable fonts 推出五年、WOFF2 成為普遍標準十年後,平均而言,網站載入字型的方式仍然不對。以下是把它做好的一頁短版說明。

The Wux Webtools Team The Wux Webtools Team 4 分鐘閱讀
Editorial illustration of a single bold letter glyph with subtle weight axis lines, soft green palette
目錄
  1. 不斷出現的模式
  2. 用一個 variable font 取代六個 static fonts
  3. 設定合理的 `font-display`
  4. 對齊 fallback metrics
  5. Self-host
  6. 什麼時候該完全跳過自訂字型
  7. 誠實總結

不斷出現的模式

如果你今天隨機稽核十個正式環境網站,你會發現其中多數都有大致相同的字型狀況:

  • 首頁載入六到十個字型檔
  • 全部都是 WOFF2(好),但沒有 font-display 策略(不好)
  • 有數個字重與樣式在頁面上完全沒有被使用
  • 整套字型從第三方網域提供(通常是 Google Fonts),連帶產生 DNS、TLS 與隱私成本
  • 沒有 unicode-range 子集化,所以即使頁面是英文,每位訪客也會下載 Cyrillic 與 Greek glyphs

這不是小型網站獨有的問題。許多資金充足的行銷頁面,仍然會在第一段文字可被繪製前載入 600 KB 的字型。一旦你開始注意到這個模式,就很難再視而不見。

修正方式並不稀奇。它只是幾個早已被理解、也已在瀏覽器中存在多年的技術。

用一個 variable font 取代六個 static fonts

如果你正在載入 Inter Regular、Inter Medium、Inter SemiBold、Inter Bold 以及 它們的斜體,你下載的位元組數大約是實際所需的六倍。一個 Inter variable font 可以用一個檔案涵蓋完整的字重軸(在某些 build 中也包含 slant),而檔案大小只比兩個靜態字重稍大一點。

瀏覽器支援這件事早已定案——variable fonts 在所有重要的地方都能運作。剩下的遲疑,多半只是 static-font 時代留下來的肌肉記憶。

實用的經驗法則:每個文字系統、每個字族用一個 variable font 檔案。Latin 一個檔案,Cyrillic 另一個,Greek 第三個,並用 unicode-range 條件式載入。就是這樣。

設定合理的 font-display

當自訂字型仍在載入時,預設行為是顯示什麼都沒有——也就是不可見文字——最長可達三秒。這是最糟的預設值。使用者看到空白頁面,會以為有東西壞了。

把這段加到每個 @font-face 規則中:

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-display: swap;
}

swap 會立即顯示 fallback font,並在自訂字型載入完成後替換進來。使用者從第零毫秒就能閱讀頁面。代價是替換發生時可能出現短暫的版面位移,而你可以用下一個技術來緩解它。

對齊 fallback metrics

未套用樣式文字的閃現,只有在 fallback 與自訂字型的 metrics 差異很大時才會顯得突兀。現代 CSS 用 size-adjustascent-override 等功能解決了這件事:

@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial');
  size-adjust: 107%;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}

調整好 fallback metrics 後,替換幾乎難以察覺——在自訂字型抵達前後,文字會佔據相同的水平空間。

Google 的 --allow-fallback-font-metrics 工作現在已成為瀏覽器基準支援,而且也有工具鏈(fontaine library 及類似工具)可以在幾秒內替你計算出正確數值。

Self-host

Four-step self-hosted font pipeline: get WOFF2 variable file, subset by script, serve from same origin with immutable cache, preload critical weight
InfographicSelf-hosting web fonts: the simple delivery pipeline — A same-origin font pipeline cuts extra origin cost and removes the privacy question

Google Fonts 很方便、免費,但也帶來兩個真實成本:

  1. 第二次 TLS handshake。 即使有 HTTP/3 與 connection coalescing,額外的 origin 也很少是免費的。
  2. 隱私與合規問題。 幾個歐洲法院已裁定,從 fonts.gstatic.com 載入 Google Fonts 構成向第三方傳輸個人資料(IP 位址)。Self-hosting 會完全移除這個問題。

下載並自行託管的流程是:

  1. 取得 WOFF2 檔案(如果有 variable build,就用它)
  2. 將它子集化到你的受眾實際使用的文字系統
  3. 從與網站其他資源相同的 origin 提供它,並設定長效 Cache-Control: max-age=31536000, immutable
  4. Preload 最關鍵的字重:<link rel="preload" as="font" type="font/woff2" href="/fonts/inter-var.woff2" crossorigin>

這就是完整流程。對既有網站來說大約花一個下午,而且你幾乎不會想走回頭路。

什麼時候該完全跳過自訂字型

這點值得明說:不是每個網站都需要自訂字型。現在的 system font stack 在每個作業系統上都確實很漂亮:

font-family: system-ui, -apple-system, 'Segoe UI', Roboto, Inter, sans-serif;

字重是對的,metrics 是對的,渲染已針對裝置調校,而線上傳輸的位元組成本正好是零。對工具網站、內部應用程式、重視內容的作品集,或任何面向慢速網路使用者的產品來說,system stack 就是正確答案。

<!-- tool-cta:start -->

💡 試試這個: 使用 Webfont Generator 將你的 TTF 或 OTF 檔案轉換為附有可直接使用 CSS 的現代 WOFF2,這正是文章建議的格式轉換。

<!-- tool-cta:end -->

誠實總結

對典型的小型網站而言,四個步驟就涵蓋了整個 web-font 效能故事:

  1. 每個字族、每個文字系統使用一個 variable font
  2. font-display: swap 搭配對齊的 fallback metrics
  3. Self-hosted,使用長效快取標頭,並為關鍵字重加入 preload
  4. 或完全跳過字型,改用 system stack

做一次,你就能從首頁拿回數百 KB,贏得幾百毫秒的感知效能,並順手移除一個第三方依賴。很少有改動能提供更好的投入報酬比。

Four-step checklist for faster web fonts: variable font, font-display swap with matched fallback metrics, self-host with cache and preload, or use system stack
InfographicThe 4-step web font performance fix — A compact playbook for reclaiming several hundred kilobytes and improving perceived performance
Comparison of six static font files versus one variable font file with script-based subsetting for Latin, Cyrillic, and Greek
InfographicFrom six static font files to one variable font — One variable file can replace a pile of weights and italics with far fewer bytes

常見問題

Variable fonts 到處都支援了嗎?
是的——所有重要的瀏覽器都已經支援 variable font 多年了。你有時聽到的遲疑,是 static-font 時代留下的肌肉記憶;在 2026 年,這不是真正的相容性顧慮。
我應該手動子集化字型嗎?
對只使用 Latin 的網站,是的——Latin subset 大約只有完整多語檔案的一半大小。對多語網站,使用 `unicode-range` 將每個文字系統作為獨立檔案載入,讓訪客只下載其內容實際需要的部分。
為什麼 font-display: swap 有時會造成難看的閃現?
因為 fallback font 的 metrics 與自訂字型不同,所以替換發生時文字會重新排版。在 fallback 上使用 `size-adjust`、`ascent-override` 與 `descent-override`,讓它匹配自訂字型的 metrics——閃現就會變得幾乎不可見。
Google Fonts 真的是隱私問題嗎?
幾項歐洲法院判決認定,從 `fonts.gstatic.com` 載入會在未經同意的情況下,將訪客 IP 傳送給第三方;在某些解釋下,這違反 GDPR。Self-hosting 會完全移除這個問題,而且通常也更快。

來源與進一步閱讀

  1. MDN — `@font-face` and `font-display`
  2. MDN — Variable fonts guide
  3. web.dev — Reduce web font size
關於作者
The Wux Webtools Team

最後更新:

繼續閱讀