- 浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
- DNS解析URL对应的IP。
- 根据IP建立TCP连接(三次握手)
- HTTP发起请求
- 服务器处理请求,浏览器接收HTTP响应。
- 渲染页面,构建DOM树。
- 关闭TCP连接(四次挥手)。
一、缓存
通常浏览器缓存策略分为两种:强缓存
和协商缓存
。
强缓存
实现强缓存可以通过两种响应头实现Expires
和Cache-Control
Expires: Wed, 22 Oct 2018 08:41:00 GMT
Expires
是 HTTP / 1.0
的产物,表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT
后过期,需要再次请求。并且 Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。
Cache-control: max-age=30
Cache-Control
出现于 HTTP / 1.1
,优先级高于 Expires
。该属性表示资源会在 30 秒后过期,需要再次请求。
协商缓存
协商缓存需要客户端和服务端共同实现,需要http请求,如果缓存有效会返回 304。
1. Last-Modified 和 If-Modified-Since
Last-Modified
表示本地文件最后修改日期,If-Modified-Since
会将 Last-Modified
的值发送给服务器,询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。
但是如果在本地打开缓存文件,就会造成 Last-Modified
被修改,所以在 HTTP / 1.1 出现了 ETag
。
2. ETag 和 If-None-Match
ETag
资源的实体标识(哈希字符串),If-None-Match
会将当前 ETag
发送给服务器,询问该资源 ETag
是否变动,有变动的话就将新的资源发送回来。并且 ETag
优先级比 Last-Modified
高。
![](https://img.haomeiwen.com/i8701263/54e70311e654988b.png)
二、DNS解析
DNS 的作用就是通过域名查询到具体的 IP。
- 首先浏览器先检查本地hosts文件是否有这个网址映射关系,如果有就调用这个IP地址映射,完成域名解析。
- 如果没找到则会查找本地DNS解析器缓存,如果查找到则返回。
- 如果还是没有找到则会查找本地DNS服务器,如果查找到则返回。
- 最后迭代查询
按根域服务器 => 顶级域
,.cn => 一级域名
,hb.cn => 二级域名
,www.hb.cn
的顺序找到IP地址。迭代查询
还有种是递归查询,区别就是前者是由客户端去做请求,后者是由系统配置的 DNS 服务器做请求,得到结果后将数据返回给客户端。
递归查询,按上一级DNS服务器->上上级->....逐级向上查询找到IP地址
![](https://img.haomeiwen.com/i8701263/baa7cbd9b38d5bf2.png)
三、TCP连接
在通过第一步的DNS域名解析后,获取到了服务器的IP地址,在获取到IP地址后,便会开始建立一次连接,这是由TCP协议完成的,主要通过三次握手进行连接。
第一次握手: 客户端向服务端发送连接请求报文段,该报文段中包含自身的数据通讯初始序号,请求发送后客户端便进入SYN_SENT
状态,等待服务器确认;
第二次握手: 服务器收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入到SYN_RECEIVED
状态;
第三次握手: 客户端收到服务器的连接同意后,还要向服务端发送一个确认报文,客户端发送完这个报文段后便进入到ESTABLISHED
状态,服务端收到这个应答以后也进入到ESTABLISHED
状态,此时连接建立成功。
![](https://img.haomeiwen.com/i8701263/9ec53d699fc7e652.png)
四、浏览器向服务器发送HTTP请求
HTTP请求格式由四部分组成,分别是请求行
、请求头
、空行
、消息体
,每部分内容占一行。
请求行
:由三部分组成:分别是请求方法(GET/POST/DELETE/PUT/HEAD)、URI路径、HTTP版本号。
请求头
:缓存相关信息(Cache-Control,If-Modified-Since)、客户端身份信息(User-Agent)、是否支持gzip压缩,等键值对信息。
空行
。
主体
:客户端发给服务端的请求数据,这部分数据并不是每个请求必须的。
![](https://img.haomeiwen.com/i8701263/f926b880e2c918ea.png)
五、浏览器接收响应
服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码
,响应头
,响应报文
三个部分。
状态码
主要包括以下部分:
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
响应头
主要由Cache-Control、 Connection、Date、Pragma等组成。
响应体
为服务器返回给浏览器的信息,主要由HTML,css,js,图片文件组成。
![](https://img.haomeiwen.com/i8701263/bb223baa4efc5709.png)
六、渲染页面,构建DOM树
如果响应的内容是HTML文档的话,就需要浏览器进行解析渲染呈现给用户。整个过程涉及两个方面:解析和渲染。
- 处理 HTML 并构建 DOM 树。
- 处理 CSS 构建 CSSOM 树。
- 将 DOM 与 CSSOM 合并成一个渲染树。
- 根据渲染树来布局,计算每个节点的位置。
- 调用 GPU 绘制,合成图层,显示在屏幕上。
在构建 CSSOM 树时,会阻塞渲染,直至 CSSOM 树构建完成。并且构建 CSSOM 树是一个十分消耗性能的过程,所以应该尽量保证层级扁平,减少过度层叠,越是具体的 CSS 选择器,执行速度越慢。
当 HTML 解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件。并且 CSS 也会影响 JS 的执行,只有当解析完样式表才会执行 JS,所以也可以认为这种情况下,CSS 也会暂停构建 DOM。
![](https://img.haomeiwen.com/i8701263/0b99764deca9d738.png)
在收到 CSS 文件后会对已经渲染的页面重新渲染,加入它们应有的样式,图片文件加载完立刻显示在相应位置。在这一过程中可能会触发页面的重绘或重排。
七、关闭TCP连接或继续保持连接
![](https://img.haomeiwen.com/i8701263/371428788bd8e1be.png)
第一次挥手
是若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。第二次挥手
B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入CLOSE_WAIT
状态,表示 A 到 B 的连接已经释放,不接收 A 发的数据了。但是因为 TCP 连接时双向的,所以 B 仍旧可以发送数据给 A。第三次握手
B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入LAST-ACK
状态。第四次握手
A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入CLOSED
状态。当 B 收到确认应答后,也便进入CLOSED
状态。
网友评论