整个过程:
1、输入 url
2、域名解析
浏览器会先查看缓存(如果之前访问过该 url,那么解析后的 ip 就会被缓存)
依次查看–
- 浏览器缓存
- 系统缓存(hosts 文件映射)
- **本地****DNS**(ISP 服务器,或者自己手动设置的 DNS 服务器)
如果都没有,则
向远程 DNS(根服务器)发送请求,启动DNS 查询,来解析域名获取 ip
不仅 web 页面的 URL 是这个流程,页面中资源的 url 也是如此
3、浏览器向服务器发起 TCP/IP 连接,在这个过程中要经历 TCP三次握手
4、握手成功(连接成功),浏览器向服务器发送 http 请求,请求数据包
5、服务器响应请求,返回数据
6、浏览器接收响应,读取页面内容
7、前端渲染阶段
- 解析 HTML,构建 DOM 树(文档对象模型树)
- 解析 CSS,构建 CSSOM 树(CSS 规则树)
- DOM**嵌套:浏览器按从上到下,从左到右的顺序将 DOM 树压入文档流**,检测节点间的层级结构,完成嵌套
- DOM**布局:将嵌套完成的 DOM 节点布局到页面上**
- 合成渲染树
- 渲染
Tips:DOM 元素是经浏览器解析后的 HTML 元素(HTML 和 DOM 的区别,先有 html,后有 dom)
三次握手
- 主机向服务器发送一个建立连接的请求;
- 服务器接到请求后发送一个同意连接的响应;
- 主机接到同意连接的响应信号后,向服务器发送一个确认信号,告知服务器已经收到请求许可
至此,主机与服务器两者就建立了连接
注意:
- 三次握手,采用的都是 TCP 协议
- 若中间有一次握手失败,根据 TCP 协议,会要求重新发送信号
扩展–四次挥手
- 主机向服务器发送一个断开连接的请求(不早了,我该走了);
- 服务器接到请求后返回一个确认收到请求的响应(知道了);
检查数据已经发送完毕后
- 服务器向主机发送一个断开连接的通知(我也该走了);
- 主机收到断开通知后断开连接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开连接;
注意:
- 为什么服务器在接到断开请求时不立即同意断开:当服务器收到断开连接的请求时,可能仍然有数据未发送完毕,所以服务器先发送确认信号,等所有数据发送完毕后再同意断开。
- 第四次握手后,主机发送确认信号后并没有立即断开连接,而是等待了 2 个报文传送周期,原因是:如果第四次握手的确认信息丢失,服务器将会重新发送第三次握手的断开连接的信号,而服务器发觉丢包与重新发送的断开连接到达主机的时间正好为 2 个报文传输周期。
DNS 域名解析优化
什么是 DNS–
DNS 是一个域名系统,是万维网上作为域名和 IP 地址相互映射的一个分布式数据库
也就是说,它是很多的电脑,专门用于存储 ip-域名映射,我们上网时需要访问它来根据域名查 ip,才能访问成功(除非你能背 ip)
显示地进行 DNS 预解析(dns-prefetch)
DNS 查询是比较耗时的,尤其当用户的网络环境较差的时候。想要节省时间,最好的办法就是让DNS 查询走缓存,这样浏览器就不用请求远程 DNS 递归查询了
dns-prefetch 原理
- 默认情况下浏览器会对页面中和当前域名(正在浏览网页的域名)不在同一个域的域名进行预获取,并且缓存结果,这就是隐式的DNS Prefetch。
- 那么,如果我们使用 link 标签,就可以将当前网页可能访问的域名预先写入页面,这样浏览器就会在用户访问这些 URL 之前进行域名预解析了。这就是显式的DNS Prefetch
- 这样,当用户访问一个 URL,浏览器就可以直接读取缓存,省去了 DNS 查询的时间
DNS Prefetch 应该尽量的放在网页的前面,推荐放在<meta charset="UTF-8">
后面
1 | <meta http-equiv="x-dns-prefetch-control" content="on"> |
预解析的实现:
- 用 meta 信息来告知浏览器,当前页面要做 DNS 预解析:
<meta http-equiv="x-dns-prefetch-control" content="on" />
- 在页面 header 中使用 link 标签来强制对 DNS 预解析:
<link rel="dns-prefetch" href="http://bdimg.share.baidu.com" />
注意:
不能滥用 dns-prefetch ,多页面重复 DNS 预解析会增加重复 DNS 查询次数。
参考:
评论