DNS Prefetching的兩三事
年前年後有點忙,又是追加功能,修改富文本編輯器,又是切我們的整體架構,好久沒有更新了,最近同事發現了個有意思的文章,如下,是講 DNS Prsfetching的。
預載入-有贊-DNS
看完之後,覺得原文,有些地方還沒有提及到,所以有必要寫一篇文章來記錄下自己的心得體會,所有原始內容來源於 Google 和 火狐 官方文檔, 正文如下:
什麼是DNS Prefetching
如果你在網上搜 DNS Prefetching的相關資料,要不就是到上面的官方文檔,要不就是基本上一致的中國版本copy & paste,如下圖所示:
- DNS 是什麼-- Domain Name System,域名系統,作為域名和IP地址相互映射的一個分散式資料庫。
- DNS大家都懂,那麼瀏覽器訪問域名的時候,是需要去解析一次DNS,也就是把域名 http://google.com解析到對應的ip地址上,相信有些人也通過修改本機hosts來翻牆訪問Google吧,這個就是主動的影響DNS解析。到這裡大家就比較清楚,既然要解析就會損耗時間,對於前端特別是移動端而言,分秒必爭,這個時間大家也想省去,所以瀏覽器廠商-Chrome最想搞了這個新功能。
- 定義--瀏覽器根據自定義的規則,提前去解析後面可能用到的域名,來加速網站的訪問速度。
看到上面不知道大家明白了 DNS Prefetching的作用和原理沒有,簡單來講就是提前解析域名,以免延遲。如果追溯的話,估計能到第二次瀏覽器大戰。
怎麼使用 DNS Prefetching呢?
使用方式其實在有贊的程序員的文章中說道了,就是
<link rel="dns-prefetch" href="[//host_name_to_prefetch.com](http://the_worlds_best_vendor.com/)">
這樣就可以出發提前解析了,那麼有贊文章中後面提到的href是怎麼回事呢?
其實原因在於Google的業務,看官方文檔中,
Solution
DNS prefetching is an attempt to resolve domain names before a user tries to follow a link. This is done using the computers normal DNS resolution mechanism; no connection to Google is used. Once a domain name has been resolved, if the user does navigate to that domain, there will be no effective delay due to DNS resolution time. The most obvious example where DNS prefetching can help is when a user is looking at a page with many links to various domains, such as a search results page. When we encounter hyperlinks in pages, we extract the domain name from each one and resolving each domain to an IP address. All this work is done in parallel with the users reading of the page, using minimal CPU and network resources. When a user clicks on any of these pre-resolved names, they will on average save about 200 milliseconds in their navigation (assuming the user hadnt already visited the domain recently). More importantly than the average savings, users wont tend to experience the "worst case" delays for DNS resolution, which are regularly over 1 second.
注意這句話:
The most obvious example where DNS prefetching can help is when a user is looking at a page with many links to various domains, such as a search results page.
所以這個功能有個默認載入條件,所有的a標籤的href都會自動去啟用DNS Prefetching,也就是說,你網頁的a標籤href帶的域名,是不需要在head裡面加上link手動設置的。
上面這點在有贊的文章也提到了,但有一點他沒有提到,a標籤的默認啟動在HTTPS不起作用。
DNS Prefetch Control
By default, Chromium does not prefetch host names in hyperlinks that appear in HTTPS pages. This restriction helps prevent an eavesdropper from inferring the host names of hyperlinks that appear in HTTPS pages based on DNS prefetch traffic. The one exception is that Chromium may periodically re-resolve the domain of the HTTPS page itself.
這一點在Mozilla的文檔也提到,甚至Firefox還有設置可以關閉相關功能。
Configuring prefetching in the browser
In general, you dont need to do anything to manage prefetching. However, the user may wish to disable prefetching. On Firefox, this can be done by setting the network.dns.disablePrefetchpreference to true.
Also, by default, prefetching of embedded link hostnames is not performed on documents loaded over HTTPS. On Firefox, this can be changed by setting the network.dns.disablePrefetchFromHTTPSpreference to false.
對於以上問題我們怎麼解決呢--使用 meta裡面http-equiv來強制啟動功能
<meta http-equiv="x-dns-prefetch-control" content="on">
以上是我們開發者需要注意的點,總結一下:
DNS Prefetching是提前載入域名解析的,省去了解析時間。
a標籤的href是可以在chrome。firefox包括高版本的IE,但是在HTTPS下面不起作用,需要meta來強制開啟功能
這是DNS的提前解析,並不是css,js之類的文件緩存,大家不要混淆了兩個不同的概念。
如果直接做了js的重定向,或者在服務端做了重定向,沒有在link裡面手動設置,是不起作用的。
這個對於什麼樣的網站更有作用呢--- 類似taobao這種網站,你的網頁引用了大量很多其他域名的資源,如果你的網站,基本所有的資源都在你本域名下,那麼這個基本沒有什麼作用。因為DNS Chrome在訪問你的網站就幫你緩存了。
深入Chrome實現底層
在Google的官方文檔中,最後介紹到Chrome針對這個功能的各種優化。
瀏覽器實現方式Chromium直接啟動了8個完全非同步的線程來做這個預解析,每個線程都處理一個隊列,等待域名響應,最終操作系統會響應一個DNS解析給線程,然後線程剔除隊列,開始下一個。因為有8個同時,基本上最多一兩個會阻塞,其他都很快執行完。所以從上也可以看出直接修改本機的hosts會影響瀏覽器的解析。也算一種簡單的翻牆方式。以下命令可以查看隊列狀態
about:histograms/DNS.PrefetchQueue
瀏覽器啟動
Chrome瀏覽器啟動的時候,就會自動的快速解析瀏覽器最近一次啟動時記錄的domin的前10個。所以一般說來你經常訪問的網址打開的速度就沒有DNS解析的延遲,更快,
Browser Startup
Chromium automatically remembers the first 10 domains that were resolved the last time the Chromium was started, and automatically starts to resolve these namesvery early in the startup process. As a result, the domains for a users home page(s), along with any embedded domains (or anything the user "always" visits just after startup), are generally resolved before much of Chromium has ever loaded. When Chromium finally starts to try to load and render those pages, there is typically no DNS induced latency, and the application effectively "starts up" (becoming usable) faster. Average startup savings are 200ms or more, with common acceleration over 1 second.
功能的有效性
如果本地就有緩存,那麼解析大概是0~1ms,如果去路由器查找大概是15ms,如果當地的伺服器,一些常見的域名可能需要150ms左右,那麼不常見的可能要1S以上。
DNS解析的包很小,因為DNS是分層協議的,不需要跟http協議一樣,一個UDP的包就ok,大概100bytes,快速。
本機的DNS緩存是有限,例如XP大概50到200個域名,所以Chrome這裡做了優化,會根據你的網站訪問頻率,來保證你常用的網站的DNS都能被緩存住。
大家可以記住以下兩個命令在chrome的地址欄輸入查看
"about:histograms/DNS" and "about:dns"
推薦閱讀:
※移動 H5(PC Web)前端性能優化指南
※前端緩存策略與基於Webpack的靜態資源版本管理
※LsLoader 移動WEB工程化緩存方案
※LsLoader 專註移動web的工程化本地緩存前端組件
※網站性能優化——DNS預熱與合併HTTP請求