綜述:域名收斂和域名發散,性能優化的重要知識
性能優化一直是前端工作中十分重要的一環,都說從 10 到 1 容易,從 1 到 0 很難。而随着前端技術的飛速發展,沒有什麼技術或者法則是金科玉律一沉不變的。
很佩服那些勇于挑戰權威,推陳出新的勇者,是他們讓我們的技術不斷的變革更加的卓越。好像扯遠了,本文主要想談談兩個名詞,域名發散和域名收斂。
域名發散
這個很好了解,前端er都知道,PC 時代為了突破浏覽器的域名并發限制,遵循這樣一條定律:
http 靜态資源采用多個子域名
嗯,為什麼要這樣做呢,目的是充分利用現代浏覽器的多線程并發下載下傳能力。
由于浏覽器的限制,每個浏覽器,允許對每個域名的連接配接數一般是有上限的,附圖一枚:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CdsVXYmVGZfVGZpNHd192LchXauV2boB3LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
上圖展示了各浏覽器的并行連接配接數(同域名),可以看到在一些現代浏覽器内每個 hostname 的最大連接配接數基本都是6個,IE 稍顯傲嬌,總體而言并發數不高。
是以 PC 時代對靜态資源優化時,通常将靜态資源分布在幾個不同域,保證資源最完美地分域名存儲,以提供最大并行度,讓用戶端加載靜态資源更為迅速。
另外,為什麼浏覽器要做并發限制呢?
- 究其根本原因,在以前,伺服器的負載能力差,稍微流量大一點伺服器就容易就崩潰。 是以為了保護伺服器不被強暴到崩潰,浏覽器要對 max connections(最大并發數)進行限制。如果每個使用者的最大并發數不限制的話,伺服器的負載能力會大幅下降。
- 另外還有一個方面就是, 防止 DDOS 攻擊。最基本的 DoS 攻擊就是利用合理的服務請求來占用過多的服務資源,進而使合法使用者無法得到服務的響應。如果不限制并發請求數量,後果,啊哦,你懂的。
域名收斂
本文的重點是想談談域名收斂,顧名思義,域名收斂的意思就是建議将靜态資源隻放在一個域名下面,而非發散情況下的多個域名下。
上面也說到了,域名發散可以突破浏覽器的域名并發限制,那麼為要反其道而行之呢?因為因地制宜,不同情況差別對待,域名發散是 PC 時代的産物,而現在進入移動網際網路時代,通過無線裝置通路網站,App的使用者已占據了很大一部分比重,而域名發散正是在這種情況下提出的。且聽我一步步分析。
http 請求過程
首先要知道,使用一個 http 請求去請求一個資源時,會經曆些什麼。簡單而言:
- DNS 域名解析 -->
- 發起 TCP 的 3 次握手 -->
- 建立 TCP 連接配接後發起 http 請求 -->
- 伺服器響應 http 請求 -->
-
......略
在這裡第一步,也是關鍵的第一步 DNS 解析,在移動端的 http 請求耗時中,DNS 解析占據了大部分時間。
說 DNS 域名解析過程前,再科普一下域名結構。
域名結構
域名的結構(或者叫命名空間)是一個樹狀結構,有樹就得有根,這個根是一個點‘.’(dot)。
以 www.example.com 為例,完整的形式應該是 www.example.com. ,注意最後一個點,就是根結點 root ,隻不過平時是浏覽器或者系統的解析器自動幫我們補全了。我們要想擷取根域都有那些,可以在終端下直接使用 dig 指令(需要安裝 dig 指令),如下:
可以看到有 13 個,大部分都是在國外,根節點之後就是頂級域名,就是.cn .com .gov 這些,頂級域劃分為通用頂級域 (com、org、net 等)和國家與地區頂級域(cn、hk、us、tw 等)。我們可以繼續使用 dig 檢視一下 頂級域名的解析路徑,加上 +trace 參數選項,意思是追蹤 DNS 解析過程,如下:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CdsVXYmVGZfVGZpNHd192LchXauV2boB3LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
可以看到是先到根節點,再查找到 com ,就是根結點會告知下一個結點 com 在哪:就是 com. 172800 IN NS [a-m].gtld-servers.net。
ok,頂級域之後就是我們熟知的一級域名,譬如 www.example.com 中的 example 就是一級域 。有興趣的可以自己試着用 dig 指令再追蹤一下:dig example.com. +trace ,可以看到是從根節點從右向左逐漸查找的。
NS 為何
上面兩張 dig 指令貼圖中間出現了很多次 NS ,NS 即是 NameServer,大部分情況下又叫權威名稱伺服器簡稱權威。
什麼是權威呢,通俗點講其實是某些域的權威,也就是權威上面有這些域的最新,最全的資料,所有這些域的資料都應該以此為準(隻有權威可以增删改這些域的資料),就像上面 dig com +trace 的結果可以看到,com 的權威是上面的 13 個根域。同理,所有的頂級域(cn、org、net 等等)的權威都是根域。
DNS 解析
其實上面就是 DNS 解析的一個大緻過程,即疊代解析,但是不是很詳盡,一個完整的 DNS 解析過程如下:
- 首先拿到 URL 後,浏覽器會尋找本地的 DNS 緩存,看看是否有對應的 IP 位址,如果緩存中存在那就好了,如果沒有,那就得向 DNS Server 發送一個請求,找到你想要的 IP 位址。
- 首先他會向你的 ISP(網際網路服務提供商) 相關的 DNS servers 發送 DNS query。然後這些 DNS 進行遞歸查詢(recursive)。所謂的遞歸查詢,就是能夠直接傳回對應的IP位址,而不是其他的 DNS server 位址。
- 如果上述的 DNS Servers 沒有你要的域名位址,則就會發送疊代查詢,即會先從 root nameservers 找起。 即是假如你要查詢 www.example.com ,會先從包含根結點的 13 台最進階域名伺服器開始。
- 接着,以從右向左的方式遞進,找到 com. 然後向包含 com 的 TLD(頂級域名) nameservers 發送 DNS 請求。接着找到包含 example 的 DNS server。
- 現在進入到了example.com 部分,即是現在正在詢問的是權威伺服器,該伺服器裡面包含了你想要的域名資訊,也就是拿到了最後的結果 record 。
- 遞歸查詢的 DNS Server 接受到這 record 之後, 會将該record 儲存一份到本地。 如果下一次你再請求這個 domain 時,我就可以直接傳回給你了。由于每條記錄都會存在 TLL ,是以 server 每隔一段時間都會發送一次請求,擷取新的 record,
- 最後,再經由最近的 DNS Server 将該條 record 傳回。 同樣,你的裝置也會存一份該 record 的副本。 之後,就是 TCP 的事了,下面是一張萌萌的簡化圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CdsVXYmVGZfVGZpNHd192LchXauV2boB3LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
到這裡,我們大緻就可以梳理一下,疊代查詢的過程如下:
流程: . => com. => .exampl.com. => www.example.com. => IP adress
TTL 為何
TTL 是 Time To Live 的縮寫,該字段指定 IP 包被路由器丢棄之前允許通過的最大網段數量。TTL 是 IPv4 標頭的一個 8 bit 字段。
簡單的說它表示 DNS 記錄在 DNS 伺服器上緩存時間。
扯了這麼多 http 請求, DNS 解析,回到正題域名收斂上,從上面可以看到,DNS 解析其實是一個很複雜的過程,在 PC 上,我們采用域名發散政策,是因為在 PC 端上,DNS 解析通常而言隻需要幾十 ms ,可以接受。而移動端,2G 網絡,3G網絡,4G網絡/wifi 強網,而且移動 4G 容易在信号不理想的地段降級成 2G ,通過大量的資料采集和真實網絡抓包分析(存在DNS解析的請求),DNS的消耗相當可觀,2G網絡大量5-10s,3G網絡平均也要3-5s(資料來源于淘寶)。 下面附上在 2G,3G,4G, WIFI 情況下 DNS 遞歸解析的時間 (ms):
因為在增加域的同時,往往會給浏覽器帶來 DNS 解析的開銷。是以在這種情況下,提出了域名收斂,減少域名數量可以降低 DNS 解析的成本。
下圖是手機端頁面加載數和域名分散數的關系(from Mobify Developer):
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CdsVXYmVGZfVGZpNHd192LchXauV2boB3LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
在 2 個域名分散條件下,網頁的加載速度提升較大,而第 3 個以後就比較慢了。 是以,一般來說,域名分散的數量最好在 3 以下。
SPDY
本來至此,本文應該結束了,談了下域名發散與域名收斂。
但是,單純的在移動端采用域名收斂并不能很大幅度的提升性能,很重要的一點是,在移動端建連的消耗非常大,而 SPDY 協定可以完成多路複用的加密全雙工通道,顯著提升非wifi環境下的網絡體驗。
俗話說,好刀配好鞘,好馬配好鞍,當域名收斂配合 SPDY 才能最大程度發揮他們的效用,達到事半功倍。
那麼什麼是 SPDY?
SPDY,一種開放的網絡傳輸協定,由Google開發,用來發送網頁内容。基于傳輸控制協定(TCP)的應用層協定 ,是 HTTP/2 的前身。
SPDY 的作用就是,在不增加域名的情況下,解除最大連接配接數的限制。主要的特點就是多路複用,他的目的就是緻力于取消并發連接配接上限。
那麼相比 http, SPDY 具體的優勢在哪裡呢:
- 多路複用 請求優化
SPDY 規定在一個 SPDY 連接配接内可以有無限個并行請求,即允許多個并發 HTTP 請求共用一個 TCP會話。這樣 SPDY 通過複用在單個 TCP 連接配接上的多次請求,而非為每個請求單獨開放連接配接,這樣隻需建立一個 TCP 連接配接就可以傳送網頁上所有資源,不僅可以減少消息互動往返的時間還可以避免建立新連接配接造成的延遲,使得 TCP 的效率更高。
此外,SPDY 的多路複用可以設定優先級,而不像傳統 HTTP 那樣嚴格按照先入先出一個一個處理請求,它會選擇性的先傳輸 CSS 這樣更重要的資源,然後再傳輸網站圖示之類不太重要的資源,可以避免讓非關鍵資源占用網絡通道的問題,提升 TCP 的性能。
- 支援伺服器推送技術
伺服器可以主動向用戶端發起通信向用戶端推送資料,這種預加載可以使使用者一直保持一個快速的網絡。
- SPDY 壓縮了 HTTP 頭
舍棄掉了不必要的頭資訊,經過壓縮之後可以節省多餘資料傳輸所帶來的等待時間和帶寬。
- 強制使用 SSL 傳輸協定
Google 認為 Web 未來的發展方向必定是安全的網絡連接配接,全部請求 SSL 加密後,資訊傳輸更加安全。
看看 SPDY 的作用圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5CdsVXYmVGZfVGZpNHd192LchXauV2boB3LcV2chVGblJ3Lc52YucWbp5GZzN2Lc9CX6MHc0RHaiojIsJye.png)
SPDY 協定在性能上對 HTTP 做了很大的優化,其核心思想是盡量減少連接配接個數,而對于 HTTP 的語義并沒有做太大的修改。
具體來說是,SPDY 使用了 HTTP 的方法和頁眉,但是删除了一些頭并重寫了 HTTP 中管理連接配接和資料轉移格式的部分,是以基本上是相容 HTTP 的。
寫到這裡,好想繼續往下寫 HTTP/2 ,因為 HTTP/2 的前身即是 SPDY 協定,但是感覺本文的内容已經很充實了,内容也很多,就不再繼續往下,内容很多,希望有人能夠耐心讀完,對一些網絡基礎知識很好的鞏固效果。