DNS Prefetching的两三事

703 查看

原文还是在简书编写的: DNS Prefetching的两三事

年前年后有点忙,又是追加功能,修改富文本编辑器,又是切我们的整体架构,好久没有更新了,最近同事发现了个有意思的文章,如下,是讲 DNS Prsfetching的。
预加载-有赞-DNS

看完之后,觉得原文,有些地方还没有提及到,所以有必要写一篇文章来记录下自己的心得体会,所有原始内容来源于 Google火狐 官方文档, 正文如下:

什么是DNS Prefetching

如果你在网上搜 DNS Prefetching的相关资料,要不就是到上面的官方文档,要不就是基本上一致的中国版本copy & paste,如下图所示:

那么DNS Prefetching 是什么 :

  • DNS 是什么-- Domain Name System,域名系统,作为域名和IP地址相互映射的一个分布式数据库。

  • DNS大家都懂,那么浏览器访问域名的时候,是需要去解析一次DNS,也就是把域名 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 computer's 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 user's 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 hadn't already visited the domain recently). More importantly than the average savings, users won't 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 don't 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.disablePrefetch
 preference 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.disablePrefetchFromHTTPS
 preference to false.

对于以上问题我们怎么解决呢--使用 meta里面http-equiv来强制启动功能
 

<meta http-equiv="x-dns-prefetch-control" content="on">

以上是我们开发者需要注意的点,总结一下:

  1. DNS Prefetching是提前加载域名解析的,省去了解析时间。

  2. a标签的href是可以在chrome。firefox包括高版本的IE,但是在HTTPS下面不起作用,需要meta来强制开启功能

  3. 这是DNS的提前解析,并不是css,js之类的文件缓存,大家不要混淆了两个不同的概念。

  4. 如果直接做了js的重定向,或者在服务端做了重定向,没有在link里面手动设置,是不起作用的。

  5. 这个对于什么样的网站更有作用呢--- 类似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 user's 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.

功能的有效性
  1. 如果本地就有缓存,那么解析大概是0~1ms,如果去路由器查找大概是15ms,如果当地的服务器,一些常见的域名可能需要150ms左右,那么不常见的可能要1S以上。

  2. DNS解析的包很小,因为DNS是分层协议的,不需要跟http协议一样,一个UDP的包就ok,大概100bytes,快速。

  3. 本机的DNS缓存是有限,例如XP大概50到200个域名,所以Chrome这里做了优化,会根据你的网站访问频率,来保证你常用的网站的DNS都能被缓存住。

大家可以记住以下两个命令在chrome的地址栏输入查看

  "about:histograms/DNS" and "about:dns"