嗯...今天要來聊聊 `dns-prefetch` 和 `preconnect`。這兩個東西...常常有人搞混,但其實它們對網頁載入效能,呃...尤其是在處理外部資源的時候,還蠻重要的。
重點一句話
如果真的沒時間,那...簡單講就是:
你非常、非常確定馬上就要跟某個外部網站拿東西,而且那個東西很重要,那就用 `preconnect`。像是...你網站一定會用到的 Google Fonts 字型。
如果你只是覺得「使用者等一下『可能』會需要」連到某個網站,但不是那麼緊急,那就用 `dns-prefetch`。這樣...至少可以先省下查 IP 的時間。
大家好像都只說了皮毛,但重點是...
我看很多文章...啊...都在解釋 `dns-prefetch` 是解析 DNS,`preconnect` 是建立連線,也就是 DNS 解析、TCP 握手,如果是 HTTPS 還要做 TLS 交握。 這個...這個是對的,但這只是在解釋「它們是什麼」。
但真正的問題是,「你怎麼決定」哪個連線是「關鍵」的,值得用更耗資源的 `preconnect`?
我自己是覺得,「關鍵」的意思是:這個資源如果沒有即時載入,使用者的畫面就會很明顯地卡住、或是破版。譬如說:
- 網站主要的字型檔,通常放在 Google Fonts 或其他 CDN 上。
- 你的單頁式應用 (SPA) 的主要 API 端點。
- 放關鍵圖片的 CDN 網域。
對於這些,你幾乎 100% 確定使用者一進來就要用到,那就值得用 `preconnect`。MDN 的文件也是建議只對最關鍵的連線使用它。 其他的,像是...一些分析工具、社群分享按鈕的腳本...那些晚一點點載入無傷大雅的,用 `dns-prefetch` 就夠了。亂用 `preconnect` 反而會因為建立太多不必要的連線,佔用頻寬,拖慢整體速度。
怎麼做?程式碼與設定方法
實作起來很簡單,就是在你 HTML 的 `
` 裡面加上 `` 標籤。如果你要預先解析一個網域的 DNS,像是 Google Analytics,可以這樣寫:
<link rel="dns-prefetch" href="https://www.google-analytics.com">
那如果你要預先「連接」到一個關鍵網域,像是 Google Fonts 的字型伺服器,會這樣寫:
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
啊對了,這邊要注意,如果預先連接的來源會需要處理 CORS,像是字型檔,就要記得加上 `crossorigin` 屬性。
更有趣的是,你可以把這兩個一起用,當作一個...嗯...備用方案。 像這樣:
<!-- 對於支援 preconnect 的瀏覽器,它會預先建立完整連線 -->
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin>
<!-- 對於只支援 dns-prefetch 的舊瀏覽器,至少還能省下 DNS 查詢時間 -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
這樣寫的好處是,比較新的瀏覽器會用 `preconnect`,得到最大的效益。但如果遇到不支援 `preconnect` 的舊瀏覽器,它雖然看不懂,但還是看得懂下一行的 `dns-prefetch`,所以...嗯...多少還是能快一點點。 我自己是覺得這算是滿好的實作方式。
一個簡單的比較表
為了方便理解,我弄了個簡單的表格...這樣比較清楚。
| 功能 | 它做了什麼? | 最佳使用情境 |
|---|---|---|
dns-prefetch |
就...先查好門牌號碼 (IP 位址)。只做 DNS 查詢。 | 你知道等一下「可能」會用到,但不緊急、也不確定是哪個。像是文章裡的外部連結、一些追蹤腳本。 |
preconnect |
不只查好門牌,還先去敲門、對方也開門了 (TCP/TLS),就等著拿東西。 | 你「非常確定」馬上就要從這個地方拿很重要的東西。像是網站主要字型、App 的主要 API。 |
什麼時候不該用?(或用了也沒用)
不過啊,這東西也不是萬靈丹,有些情況下用了也沒幫助,甚至有害。
- 用在自己的網站網域:`dns-prefetch` 和 `preconnect` 都是針對「跨來源」(cross-origin) 的網域。如果你要連的資源跟你網頁在同一個網域,那瀏覽器早就連線了,再加這個是多此一舉。
- 加了太多的 `preconnect`:我前面提過了,每個 `preconnect` 都會佔用系統資源和頻寬。你如果對十幾個網域都 `preconnect`,那...光是建立這些連線可能就把網路塞住了,反而拖慢了真正重要的資源下載。 最好不要超過...嗯...兩三個最關鍵的就好。
- 太晚才被發現的資源:這些提示最好放在 `` 的越前面越好。 如果你用 JavaScript 在頁面很後面才動態插入一個 `preconnect` 標籤,那時候...可能瀏覽器都已經自己開始連線了,效果就大打折扣。
所以...總結一下,這不是什麼黑魔法。它就是一個...你知道的,提前跟瀏覽器打個招呼的機制,讓它可以預先做點準備,減少之後的等待時間。 關鍵還是在於你要能判斷,什麼資源是「值得」你花費額外資源去預先準備的。
對了,你們的網站上...最常連的第三方域名是什麼啊?像是 GA、還是 FB pixel?...有用 preconnect 嗎?留言分享看看你們是怎麼用的吧。
