Google webFont 直接引入使用所產生的問題

在外部資源來說,以網頁最需要取得相關的圖片與型字資源後,才能進行後續程式碼的規劃,圖片載入頁面又由其重要,除非頁面是給容器固定的高寬度值,不然也會對頁面上的佔位空間有所影響。

此外字體部份影響上比較沒像圖片會和版面呈現上較直接,可以先透過網頁安全字體進行渲染,直到 webFont 取得資源後在將畫面上的字體做一次更動。以上的部份多少會影響到使用者體驗,透過取得資源的順序方式改善。


快取與取用資源

preload、prefetch 於 HTTP Cache 與 Memory Cache 的快取方式

preloadprefetch 取得的資源都會存在 HTTP Cache 中,再放到 Memory Cache,不能快取的話就只會在 memory cache。
preloadprefetch 在取得資源前會先查詢快取,若快取沒過期就用快取的檔案不再重抓。

資源優先取用順序

1. Highest: HTML, CSS, Fonts
2. High: script (預載影像之前), 在 viewport 內的影像
3. Medium: script
4. Low: script (async), image, media
5. Lowest: mismatched CSS, prefetch resources

來源:Preload, Prefetch And Priorities in Chrome


preload、prefetch、preconnect

preload、prefetch、preconnect 標籤的使用概念

以近代主流瀏覽器來說,大約於 2020 年的前後也都有大約有支援 HTML 標籤屬性 rel 的用法,查看到 2021 後的瀏覽器上也大都可使用。
caniuse – Resource Hints: preload
caniuse – Resource Hints: prefetch

preload:此資源對目前的頁面是必要的,請用最快的速度下載此資源。
preconnect:此網頁不久後將來下載某個 domain 的資源,先行建立連線
prefetch:此資源等等才會用到,有空在下載

關鍵轉譯路徑最佳化 HTML、CSS、JS,影響使用者體驗

關鍵轉譯路徑用來改善網頁效能,優先顯示與使用者要在網頁上執行的主要操作有關的內容。
收到 HTML、CSS 和 JavaScript 位元組,再對程式碼進行必需的處理,到最後轉變為顯示像素的過程中還有許多中間步驟。將效能最佳化其實就是瞭解這些步驟中所有的活動,這就是所謂的關鍵轉譯路徑。

Optimized (優化) 與 Unoptimized (未優化) 的畫面渲染處理方式。

Google developers — 關鍵轉譯路徑

preload:開啟頁面優先取連結資源

preload:此資源對目前的頁面是必要的,請用最快的速度下載此資源。

CSS 與 JS 的使用

rel="preload" 標籤,以 as 指定 script 或是 style 資源類型。

script 一般放在 html 的最後面,等到 parse 完整個 html 被執行。
重要的資源以 preload 是比較好的優化方式。相較之下使用非同步下載資源 async script 較會會產生出 block onload event (阻止加載事件)。

Font 的使用

rel="preload" 標籤,以 as 指定 font 資源類型。
crossorigin="anonymous" (跨域屬性設定) 列為需要加的屬性,以 anonymous mode CORS 方式取得資源,否則字體會被重複下載兩次。

HTML5 部份元素有 CORS 的支援,可見 HTML5標簽的crossorigin屬性,提供元素CORS跨域設定 一文。

preconnect:將連結的 domain 資源先建立好連線

preconnect:此網頁不久後將來下載某個 domain 的資源,先行建立連線

提前建立連線,瀏覽器在實際傳輸資源前有幾個需要的步驟。
1. 向 DNS 請求解析域名
2. TCP Handshake (TCP 交握)
3. SSL Negotiation (HTTPS 連線)
4. 連線建立完成,等待拿到資料的第一個 byte

以 preconnect 的使用上,基本上可應用於 CDN 或是 Streaming (串流媒體) 上,在切換頁面前可以先進行取得資源進入到快取,當連結下一頁時結省下時間開啟頁面所建立連結的時間。

prefetch:等下用到的資源待必較資源取得後接續取

prefetch:此資源等等才會用到,有空在下載
prefetch 主要是用在同頁資源時預先載入,資源等頁面完全下載完以後以 Lowest (最低) 優先度下載。
在同頁用 JS 的 AJAX 行為抽換局部內容,若資源檔過大,排於 preload 優先必取資源先渲染主要頁面後,之後以 prefetch 接著於背後取得後續資源,在處理畫面抽換區塊內容,可達到較好的呈現 (例如:抽換高解析圖檔抽換區塊會漸漸呈現圖片)。


preload 實作 Google webFont

以下以 Noto Sans Traditional Chinese 使用 link 方式戴入字體資源。

preconnect 於主要資源取得後,再取 Google webFont (官方預設產生連結方式)

直接以 Google webFont 官方引入方式,透過 <link rel="preconnect"> 方式引入。

引入結果查看到開發者工具,會發現因為 <link rel="preconnect"> 取用字體資源,會於相關資源都引入後,在頁面結構產生時才進行取得字體,所以相關字體會是在後方。

小結:這樣引用字體資源的方式,有個好處是可配合上瀏覽器安全字體先處理畫面,待 webFont 資源取得後再進行重新更換顯示字體。

改用 preload 將字體於頁面優先取得

以思源繁中字體,引入的資源檔相當多,詳見 https://fonts.googleapis.com/css2?family=Noto+Serif+TC:wght@900&display=swap,每個 @font-face {}src: url() 就是對應的字體資源。

針對 src: url() 相關的字體資源,直接置於 HTML head 結構中的 <link>,加入屬性 rel="preload"as="font",並開啟頁面透過開發者工具查看。

引入結果查看到開發者工具,會發現到相關的字體資源都提於前面,相關資源都完整取得後,才會透過渲染畫面。

小結:在取得資源時,因為是主要優先取得,如果裝置的網速不快,會產生過久的空白畫面。

JS 要規劃優先取得資源後才渲染畫面,另可使用 Web Font Loader (字體載入事件) 的 JS 插件,套件主要目的就是以 Javascript 的方式載入Web Font,並透過傳遞一些參數,來改變載入 Web Font 行為,待取得資源與字體載入完成後,才進行畫面渲染。
Web Font Loader 網頁字體裝載機 (繁中文件說明)


資料參考