哈囉各位,最近在幫客戶看網站速度,發現一個老問題,但還是很多人踩雷:就是「網頁字體」!
大家為了讓網站漂亮,都會用一些特別的字體(Web Fonts),這沒問題。但如果沒設定好,它會變成拖慢你網站、甚至影響 SEO 排名的元兇!😱 想像一下,使用者點進你的網站,結果文字區塊一片空白,過了兩三秒字才「啪」地一聲跳出來,有時候版面還會跟著抖一下... 這體驗超差的,對吧?
先說結論
簡單講,你用的外部字體(Web Fonts)在載入完成前,瀏覽器不知道要顯示什麼,所以會出現文字空白(FOIT)或是版面位移(CLS)的問題。 這兩個都會讓你的 PageSpeed 分數變很醜,Google 不喜歡,使用者也不喜歡。
不過呢,要解決這問題,大部分情況下你只需要在 CSS 的 @font-face 規則裡,加上一行 `font-display: swap;` 就搞定了。 真的,就這麼簡單。但如果你想做到極致,或是想徹底理解背後的原理,那後面還有更多可以玩的東西。我們接著看下去。😉
字體沒搞好,到底會發生什麼事?(有圖有真相)
OK,我們來聊聊兩個最常見的狀況:FOIT 跟 FOUT。
- FOIT (Flash of Invisible Text):字體檔案還在下載時,文字區塊是「完全空白」的,像隱形了一樣。等字體載好後,文字才會突然出現。 這是最糟糕的體驗,因為使用者會盯著白畫面發呆,不知道發生了什麼事。
- FOUT (Flash of Unstyled Text):這個好一點。瀏覽器會先用電腦裡預設的「後備字體」(例如新細明體或 Arial)顯示文字,等你的酷炫字體載好後,再「換」過去。 這樣至少使用者能先看到內容。`font-display: swap` 就是在做這件事。
但 FOUT 也不是完美的。如果你的後備字體跟 Web Font 長得差很多(比如一個高胖、一個矮瘦),在交換的那一瞬間,整個頁面的排版就會「抖」一下。這個「抖動」就是 Google Core Web Vitals 裡面很在意的 **CLS (Cumulative Layout Shift,累計版面配置位移)**。 CLS 分數太高,代表你的網頁很不穩定,會影響使用者體驗,當然也會間接影響 SEO 排名。
說到 CLS,這真的超煩的。有時候你看文章看到一半,突然一個廣告或圖片載入,整篇文章跳掉,又要重新找讀到哪... 字體也會搞這種事! 看看你的 PageSpeed Insights 報告,如果 CLS 那一項是紅字,字體八成是兇手之一。
OK,那到底要怎麼做?
來,我們從最簡單、CP 值最高的開始。90% 的問題靠這招就能解決。
你只需要在你的 CSS 檔案裡,找到定義自訂字體的地方,也就是 `@font-face`,然後在裡面加上 `font-display: swap;` 就行了。
這段程式碼的意思就是告訴瀏覽器:「喂!先用系統預設字體顯示文字,等我指定的字體下載完你再換上來!」
@font-face {
font-family: '你的超酷字體';
src: url('/fonts/your-font.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap; /* <-- 就是加這一行! */
}
如果你是用 Google Fonts,而且是直接複製它提供的 `` 貼到 HTML 的 `
`,好消息是 Google 現在預設就會幫你加上 `display=swap` 參數了。但如果你是幾年前設定的,最好還是檢查一下喔!進階班:除了 swap 還能玩什麼?
如果你是個完美主義者,或是 `swap` 之後的版面抖動還是讓你很阿雜,那恭喜你,歡迎來到進階班。這裡有幾個你可以玩的東西:
1. 字體子集化 (Subsetting)
這招超級、超級重要,尤其是對我們用中文的人來說。一個完整的中文字體檔動輒 10MB 以上,載到天荒地老。但你的網站真的需要「魑魅魍魎」這些字嗎?大概不用吧 😂
「字體子集化」就是只打包你會用到的字元,產生一個迷你的字體檔。 比如說,你的網站只會用到「首頁、關於我們、最新消息、聯絡我們」這些字,那你就把這些字加上一些常用字打包起來就好。檔案大小可能從 10MB 瞬間變成 50KB,載入速度是火箭級的提升!🚀
有很多線上工具可以做這件事,Google 一下「font subsetting tool」就很多。justfont 這類台灣的字體服務商,也都有提供很方便的雲端子集化服務。
2. 本地託管 (Self-hosting)
以前大家會覺得用 Google Fonts 的 CDN (內容傳遞網路) 比較快,因為別人家的網站如果也用同一個字體,使用者的瀏覽器可能已經快取了,就不用再下載一次。
但這個論點現在已經過時了!從 2020 年開始,主流瀏覽器(像 Chrome 和 Safari)為了隱私和安全,都採用了「快取分區 (Cache Partitioning)」技術。 簡單說,A 網站的快取,B 網站不能共用。所以那個「跨站快取」的優勢已經沒了。
反過來說,如果你把字體檔放在自己的主機上(本地託管),瀏覽器就可以重複利用同一個連線來下載 HTML、CSS 和字體,省去了跟 Google 伺服器建立新連線的時間(DNS 查詢、SSL 交握...等)。 在 HTTP/2 或 HTTP/3 的環境下,這個優勢更明顯。
所以,目前的最佳實踐是:把「子集化」後的字體檔,放在你自己的主機上,然後用 `@font-face` 載入。
3. 終極大魔王:用 size-adjust 精準控制 CLS
這招就真的比較 hardcore 了,但效果拔群!我是在 web.dev (Google 官方的開發者網站) 上看到這個技巧的,但在台灣的實作分享還比較少。
前面提到,`swap` 的問題是後備字體和 Web Font 大小不一會造成抖動。 那如果... 我們有辦法在 Web Font 載入前,先把後備字體的「尺寸」調整得跟 Web Font「幾乎一模一樣」呢?
沒錯!CSS 現在提供了幾個新的描述符:`size-adjust`、`ascent-override`、`descent-override`。 你可以用這些屬性去微調後備字體的顯示大小、基線上方和下方的高度,讓它看起來就跟你的目標 Web Font 幾乎一樣。這樣一來,當字體 `swap` 交換的那一刻,因為前後尺寸幾乎沒變,CLS 就不會發生了!
/* 這是為了讓後備字體 Arial 模擬成目標字體 Poppins */
@font-face {
font-family: 'Poppins-fallback';
size-adjust: 95.65%;
ascent-override: 92%;
src: local('Arial');
}
body {
/* 使用時,先指定 fallback,再指定真正的字體 */
font-family: 'Poppins-fallback', 'Poppins', sans-serif;
}
要算出這些精確的百分比數字有點麻煩,不過網路上已經有神人做了計算機 (搜尋 "size-adjust calculator"),你只要上傳兩個字體檔,它就能幫你算出這些魔法數字。 這對於追求極致體驗的網站來說,絕對是個神器。
各種載入方式大亂鬥
為了讓大家更清楚,我整理了一下不同 `font-display` 值的差別,用比較口語的方式解釋:
| font-display 值 | 白話文解釋 | 優點 | 缺點 |
|---|---|---|---|
block |
霸道總裁型:「字體沒載好前,啥都別給我看!」 | 能保證使用者第一眼看到的就是最終設計。 | 使用者會盯著白畫面發呆 (FOIT),體驗超差,LCP 分數會很慘。 |
swap |
效率優先型:「先隨便找個字頂著,好了再換!」 | 文字能最快顯示,對 LCP (最大內容繪製) 指標很有幫助。 | 如果後備字體跟目標字體差太多,替換時會抖一下 (CLS)。 |
fallback |
有點耐心型:「我等你 100ms,再不來我就先用別的字... 你載好後我再看情況換。」 | 算是 block 跟 swap 的折衷。如果網路快,體驗跟 block 差不多。 | 如果網路慢,還是會先 FOUT 再交換,存在 CLS 風險。 |
optional |
佛系隨緣型:「我只等你一下下 (100ms),你不來就算了,我就用後備字體到底。」 | 對於非核心、裝飾性的字體很棒。能保證絕不發生 CLS。 | 使用者可能永遠看不到你精心挑選的字體,如果這個字體對品牌很重要就不適合。 |
常見錯誤與修正
最後,整理幾個大家最常犯的錯:
- 還在迷信 Google Fonts CDN 比較快:就像前面說的,因為快取分區的關係,這個優勢已經沒了。 大膽地把字體抓下來放自己家吧!
- 只用 WOFF2 格式:現在主流瀏覽器都支援 WOFF2 格式了,它的壓縮率比 WOFF 或 TTF 好非常多,檔案小很多。 除非你要支援 IE 這種上古神獸,不然 `@font-face` 裡只放 WOFF2 就夠了。
- 一個網站用太多字體:設計師可能會很想用 5 種不同的字體,但拜託不要。每多一個字體(或字重),就是多一個 HTTP 請求,都會拖慢速度。 盡量控制在 1-2 種字體家族內就好。
所以,我該怎麼選?
老實說,我自己是覺得,對於 90% 的網站(部落格、形象網站、中小型電商),你只要做到:
- 挑 1-2 個字體。
- 把字體子集化,只打包常用字。
- 把產生出來的 WOFF2 檔案丟到自己主機上。
- 在 CSS 裡用 `font-display: swap;`。
這樣你的網站速度跟體驗就已經贏過很多人了。如果你是像素級的完美主義者,或是你的網站 CLS 問題很嚴重,那再去研究 `size-adjust` 那些進階技巧,絕對能讓你網站的體質更上一層樓。💪
好了,今天就先分享到這。你自己的網站是用什麼字體?有用 Web Fonts 嗎?歡迎留言分享一下你的 PageSpeed 分數,或是有沒有踩過什麼有趣的坑!😂
