从浏览器输入一个url回车都发生了什么
这个是一个测试片段
从一个经典的问题说起,从浏览器输入一个url回车都发生了什么???
有点计算机基础的人想必都能说出一二,那就是

作为一枚前端开发,在整个过程中,其实我们都知道有很多性能优化的方式。今天我们来聊聊在第一阶段如何来做优化。引出今天的话题: DNS预解析。
第一步就是DNS预解析,DNS 作为互联网的基础协议,其解析的速度似乎容易被网站优化人员忽视。现在大多数新浏览器已经针对DNS解析进行了优化,典型的一次DNS解析耗费20-120 毫秒,减少DNS解析时间和次数是个很好的优化方式。DNS Prefetching是具有此属性的域名不需要用户点击链接就在后台解析,而域名解析和内容载入是串行的网络操作,所以这个方式能减少用户的等待时间,提升用户体验。
一、原理
Domain Name System 将域名和IP地址相互映射的一个分布式数据库
DNS 预读取是一项使浏览器主动去执行域名解析的功能,其范围包括文档的所有链接,无论是图片的,CSS 的,还是 JavaScript 等其他用户能够点击的 URL,减少用户点击链接时的延迟。一句话概括就是在 HTTP 建立之前,将 DNS 查询的结果缓存到系统/浏览器中,提升网页的加载效率
当浏览器访问一个域名的时候,需要解析一次DNS,获得对应域名的ip地址。
浏览器缓存 => 系统缓存 => 路由器缓存 =>ISP(运营商)DNS缓存 => 根域名服务器 => 顶级域名服务器 => 主域名服务器的顺序
逐步读取缓存,直到拿到IP地址
作用:根据浏览器定义的规则,提前解析之后可能会用到的域名,使解析结果缓存到系统缓存中,缩短DNS解析时间,来提高网站的访问速度
二、使用
1、打开和关闭DNS预解析
希望在HTTPS页面开启自动解析功能时,添加如下标记
1 | <meta http-equiv="x-dns-prefetch-control" content="on"> |
也可以通过在服务器端发送 X-DNS-Prefetch-Control 报头
2、自动解析
Chromium会自动解析href属性(a标签),该行为与用户浏览网页是并行的。但为了确保安全,HTTPS页面不会自动解析
DNS Prefetching - Chromium官方文档
Chromium不使用浏览器的网络堆栈,直接使用操作系统的缓存。通过8个异步线程执行预解析,每个线程处理一个队列,来等待域名的响应,最终操作系统会响应一个DNS结果给线程,然后线程丢弃它,等待下一个预解析请求。
3、手动添加解析
1 | <link rel="dns-prefetch" href="http://www.google.com"> |
4、在浏览器中设置
一般来说并不需要去管理预读取,但是可能会有用户希望关闭预读取功能。这时只需要设置 network.dns.disablePrefetch preference 值为 true 就可以了
默认情况下,通过 HTTPS 加载的页面上内嵌链接的域名并不会执行预加载。在 Firefox 浏览器中,可以通过设置 network.dns.disablePrefetchFromHTTPS 值为 false 来改变这一默认行为。
三、淘宝怎么做的
webpagetest上输入淘宝的地址https://www.taobao.com


可以看出解析时间比较长的域名没有在这个列表中。
四、使用场景
1、新用户访问,后端可以通过 Cookie 判断是否为首次进入站点,对于这类用户,DNS Prefetch 可以比较明显地提升访问速度
2、登录页,提前在页面上进行下一跳页用到资源的 DNS Prefetch
2、上面说到chrome使用了8个异步线程来处理DNS预解析,所以过多的prefetch并不一定能提高网页加载效率
五、如何更好的使用
1、对哪些资源做手动prefetch
- 静态资源域名
- JS里会发起跳转的域名
- 会重定向的域名
2、不用对超链接做手动prefetch,浏览器会自动做
3、手动DNS预解析还可以优化吗
实际上还是会增加html的代码量的,特别是域名多的情况下
可以通过js初始化一个iframe异步加载一个页面,而这个页面里包含本站所有的需要手动dns prefetching的域名
4、页面Head里面有个css链接, 在当前页的Head里加上对应的手动dns prefetching的link标签,实际上并没有好处
六、域名发散和域名收敛

1、域名发散
在PC上,为了突破浏览器的单域名多线程并发限制,大家会采用域名发散:http 静态资源采用多个子域名,以提供最大并行度,让客户端加载静态资源更为迅速
为什么浏览器要做并发限制?
- 以前的服务器负载能力差,流量大容易奔溃,所以为了保护服务器,浏览器做了单域名最大并发限制
- 防止DDOS攻击,最基本的 DoS 攻击就是利用合理的服务请求来占用过多的服务资源,从而使合法用户无法得到服务的响应。
2、域名收敛
顾名思义:尽量将静态资源只放在一个域名下面
既然域名发散优点这么明显,那么域名收敛怎么来的?
上面说了是PC下使用域名发散,那么现在是移动互联网时代,无线设备占多(写这个文章的时候是2018年末,5G都快来了,地域和网速限制马上不会再成为瓶颈,但还是要究其根本)
首先,HTTP请求需要经历这么个过程
DNS域名解析 -> TCP 3次握手 -> 发起HTTP请求 -> 服务器响应HTTP请求 -> …… -> 浏览器解析渲染页面
第一个DNS解析是一个很复杂的过程,此处略过…
PC上DNS解析消耗相对较小
但移动端(假设信号不够强)的DNS消耗是比较可观的(相对而言)
所以,在增加域名的同时,会带来一定的DNS解析消耗,所以域名收敛能降低这个成本。
但是,单纯的靠域名收敛降低这个成本,貌似对性能提升是个鸡肋
那么单域名的并发问题还是存在,怎么处理,核心是解除最大连接数的限制,那么SPDY/HTTP2的多路复用功能就派上用场了
这两新协议对HTTP1.1做了不少的优化,核心是减少连接数,还有头部压缩、服务器推送,强制SSL安全协议等等
总的来说,尽快拥抱新技术吧~~~
https://developer.mozilla.org/zh-CN/docs/Controlling_DNS_prefetching
https://github.com/amandakelake/blog/issues/50