DNS 預取與預連接策略:網頁載入效能優化的實作原理與設定方法

Published on: | Last updated:

嗯...今天要來聊聊 `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`,所以...嗯...多少還是能快一點點。 我自己是覺得這算是滿好的實作方式。

在 HTML Head 中實作的程式碼範例
在 HTML Head 中實作的程式碼範例

一個簡單的比較表

為了方便理解,我弄了個簡單的表格...這樣比較清楚。

功能 它做了什麼? 最佳使用情境
dns-prefetch 就...先查好門牌號碼 (IP 位址)。只做 DNS 查詢。 你知道等一下「可能」會用到,但不緊急、也不確定是哪個。像是文章裡的外部連結、一些追蹤腳本。
preconnect 不只查好門牌,還先去敲門、對方也開門了 (TCP/TLS),就等著拿東西。 你「非常確定」馬上就要從這個地方拿很重要的東西。像是網站主要字型、App 的主要 API。

什麼時候不該用?(或用了也沒用)

不過啊,這東西也不是萬靈丹,有些情況下用了也沒幫助,甚至有害。

  • 用在自己的網站網域:`dns-prefetch` 和 `preconnect` 都是針對「跨來源」(cross-origin) 的網域。如果你要連的資源跟你網頁在同一個網域,那瀏覽器早就連線了,再加這個是多此一舉。
  • 加了太多的 `preconnect`:我前面提過了,每個 `preconnect` 都會佔用系統資源和頻寬。你如果對十幾個網域都 `preconnect`,那...光是建立這些連線可能就把網路塞住了,反而拖慢了真正重要的資源下載。 最好不要超過...嗯...兩三個最關鍵的就好。
  • 太晚才被發現的資源:這些提示最好放在 `` 的越前面越好。 如果你用 JavaScript 在頁面很後面才動態插入一個 `preconnect` 標籤,那時候...可能瀏覽器都已經自己開始連線了,效果就大打折扣。
使用 preconnect 前後網路瀑布圖對比
使用 preconnect 前後網路瀑布圖對比

所以...總結一下,這不是什麼黑魔法。它就是一個...你知道的,提前跟瀏覽器打個招呼的機制,讓它可以預先做點準備,減少之後的等待時間。 關鍵還是在於你要能判斷,什麼資源是「值得」你花費額外資源去預先準備的。

對了,你們的網站上...最常連的第三方域名是什麼啊?像是 GA、還是 FB pixel?...有用 preconnect 嗎?留言分享看看你們是怎麼用的吧。

Related to this topic:

Comments

  1. profile
    Guest 2025-06-18 Reply
    哇靠,網站優化真的是門大學問!剛學了點前端,才發現效能調校超燒腦。DNS預取這種技術聽起來好酷,感覺可以再深入研究一下,對網站速度應該有不小的幫助吧!
  2. profile
    Guest 2025-06-06 Reply
    作為一個來自矽谷的技術愛好者,我超愛研究網站優化!DNS預取真的是個超級酷的技術,尤其是在跨國網路環境中。不過,每個地區的網路基礎建設差異還滿大的,得客製化調整呢!
  3. profile
    Guest 2025-05-23 Reply
    聽說 DNS 預取很厲害,不過我還是有點懷疑啦。學長們的網站都超級快,我的卻像烏龜一樣爬行。有空能不能分享一下實際經驗?
  4. profile
    Guest 2025-04-29 Reply
    我覺得網站載入速度真的很重要,尤其是對我們這些大學生來說,上課時常常需要查資料。如果網站太慢,會浪費很多時間!除了DNS預取和預連接外,有沒有其他有效的方法可以加速呢?