seo网页加速技术,预加载 DNS Prefetching 详解
DNS Prefetching 是什么 :
DNS 是什么-- Domain Name System,域名系统,作为域名和IP地址相互映射的一个分布式数据库。
DNS大家都懂,那么浏览器访问域名的时候,是需要去解析一次DNS,也就是把域名 google.com解析到对应的ip地址上,修改本机hosts就是主动的影响DNS解析。
既然要解析就会损耗时间,对于前端特别是移动端而言,分秒必争,所以浏览器厂商-Chrome最想搞了这个新功能。
定义--浏览器根据自定义的规则,提前去解析后面可能用到的域名,来加速网站的访问速度。
DNS Prefetching的作用和原理就是提前解析域名,以免延迟。如果追溯的话,估计能到第二次浏览器大战。
怎么使用 DNS Prefetching呢?
使用方式:
<link rel="dns-prefetch" href="[//host_name_to_prefetch.com](http://the_worlds_best_vendor.com/)">
实例:
<link rel="dns-prefetch" href="//www.ssqhm.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">
以上是我们开发者需要注意的点,总结一下:
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 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.
功能的有效性
如果本地就有缓存,那么解析大概是0~1ms,如果去路由器查找大概是15ms,如果当地的服务器,一些常见的域名可能需要150ms左右,不常见的可能要1S以上。
DNS解析的包很小,因为DNS是分层协议的,不需要跟http协议一样,一个UDP的包就ok,大概100bytes,快速。
本机的DNS缓存是有限,例如XP大概50到200个域名,所以Chrome这里做了优化,会根据你的网站访问频率,来保证你常用的网站的DNS都能被缓存住。
以下两个命令在chrome的地址栏输入查看:
"about:histograms/DNS" and "about:dns"
正确的使用方式:
1.对静态资源域名做手动dns prefetching。
2.对js里会发起的跳转、请求做手动dns prefetching。
3.不用对超链接做手动dns prefetching,因为chrome会自动做dns prefetching。
4.对重定向跳转的新域名做手动dns prefetching,比如:页面上有个A域名的链接,但访问A会重定向到B域名的链接,这么在当前页对B域名做手动dns prefetching是有意义的。
其他
1.假设页面Head里面有个css链接, 在当前页的Head里加上对应的手动dns prefetching的link标签,实际上并没有好处。
2.普遍来说合理的dns prefetching能对页面性能带来50ms ~ 300ms的提升,有人做了这方面的统计。
3.如chromium的官方文档所说,dns prefetching的网络消耗是极低极低的:
Each request typically involves sending a single UDP packet that is under 100 bytes out, and getting back a response that is around 100 bytes. This minimal impact on network usage is compensated by a significant improvement in user experience.
4.如chromium的官方文档所说,chrome使用8个线程专门做dns prefetching 而且chrome本身不做dns记录的cache,是直接从操作系统读dns --直接修改系统的dns记录或者host会直接影响chrome。
5.手动dns prefetching的代码实际上还是会增加html的代码量的,特别是域名多的情况下。
所以,最优的方案应该是:通过js初始化一个iframe异步加载一个页面,而这个页面里包含本站所有的需要手动dns prefetching的域名。