从输入url到页面加载发生了什么?
过程:
1、 域名解析(获得IP地址)
2、 发起TCP连接
3、建立TCP连接后发起HTTP请求
4、服务器端处理HTTP请求,浏览器接收HTTP响应。
5、浏览器解析渲染页面
一、域名解析
DNS解析的过程就是寻找哪台机器上有你需要的资源的过程,互联网上每一台计算机的唯一标识就是它的IP地址,所以域名解析会将一个网址转换为IP地址。
解析过程:
上图是查找www.google.com的IP地址的过程。
首先在本地域名服务器中查找ip地址,如果没有找到,本地域名服务器会向根域名服务器发送一个请求。
如果根域名服务器也没有,则根域名服务器会向com顶级服务器发送请求,以此类推下去。
直到最后本地域名服务器获得ip地址并把它缓存到本地,供下次查询使用。
从上述过程中,可以看出解析过程是从右向左的:. ->com->google.com->www.google.com
具体过程:
(1)在浏览器缓存中查找该域名对应的IP地址;
(2)在本机系统查找是否缓存过IP,(系统自己也具备域名解析的能力);
(3)向本地域名服务器发送请求
本地域名系统一般是本地区的域名服务器,比如连接的校园网,那么域名解析系统就在校园的机房里;如果连接的是电信、移动等网络,那么本地域名解析系统就在北地区,有各自的运营商来提供服务。
(4)向根域名服务器发送请求。
。。。。。
查询的两种方式:
(1)递归查询。
如果主机所询问的本地域名服务器不知道被查询的域名的ip地址,那么本地域名服务器就以DNS客户的身份,向其他根域名服务器继续发出查询请求报文,而不是让主机自己进行下一步查询。
(2)迭代查询 (每次都需要本地域名服务器去查找)
当根域名服务器收到本地域名服务器发出的迭代查询请求报文时,要么给出所要查询的ip地址,要么告诉本地服务器下一步应该向哪一个域名服务器进行查询,然后让本地域名服务器进行后续查询。
DNS负载均衡
当用户访问量巨大时,同时访问主机会使主机崩掉,因此使用负载均衡来解决这个问题。
原理:在DNS服务器中为同一主机分配多个IP地址(也就是多个服务器),当进行DNS解析时,通过算法根据主机的负载情况,返回IP地址。
DNS缓存
DNS存在着多级缓存,按照离浏览器的距离排序的话,有:浏览器缓存、系统缓存、路由器缓存、IPS服务器缓存、根域名服务器缓存、顶级域名服务器缓存、主域名服务器缓存。
优化:减少DNS解析的时间。
二、TCP连接
HTTP协议是使用TCP作为其传输层协议的。
TCP首部:默认长度为20B,包括源端口、目的端口、序号、确认号等。
第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;SYN:同步序列编号(Synchronize Sequence Numbers)。
第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
第一步:客户端向服务器发出连接请求的报文段,其首部中的同步位SYN=1(SYN报文不能携带数据,但是要消耗一个序号),并选择序列号seq=x,表明传送数据时的第一个数据字节的序号是x。
第二步:服务器收到数据报,并从SYN=1知道这是一个建立连接的请求,如果同意,则发回确认;服务器在确认报文中应使用SYN=1,ACK=1,其确认号ack=x+1,自己的序列号为seq=y。
第三步:客户端收到报文段后向服务器给出确认,其ACK=1,确认ack=y+1。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
TCP连接为什么不能是两次或者四次?
假设没有第三次握手,服务器在客户端的请求进行响应(第二次握手)后,就会理所当然的认为已经建立连接了,但是在返回相应过程中可能会丢包,如果客户端并没有收到服务端的确认包的话,会认为连接未建立,然而服务端会对已建立的连接保存必要的资源。所以不能是两次。
完全可靠的通信协议是根本不存在的,而三次握手之后,客户端和服务端至少可以确认之前的通信情况,但是无法确认之后的情况。所以无论是四次还是五次dou'shi 徒劳的,所以三次是最佳的次数。
三、发送HTTP请求
HTTP请求报文是由三部分组成:请求行、请求头和请求正文
请求行:
格式:Method Request-URL HTTP-Version CRLF
例:GET index.html HTTP/1.1
请求行包括请求方法、url字段以及http协议版本
常用Method方法有:GET、POST、PUT、DELETE
请求头:
作用:允许客户端向服务器传递请求的附加信息和客户端的信息
常见的请求头有: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Content-Type, Authorization, Cookie, User-Agent等。
请求正文:
当使用POST或PUT方式时,表示客户端需要向服务器端传输数据,传输的数据放在请求正文中,同时请求头中也会包含一些与请求正文相关的数据。
如:当请求的数据采用json的数据格式时,需要设置请求头的Content-Type:Application/json。
优化:
减少HTTP请求次数:如合并文件、雪碧图等。
四、服务器处理请求并返回HTTP响应
HTTP响应报文由三部分组成:状态码、响应头和响应报文。
状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值:
-
1xx:指示信息–表示请求已接收,继续处理。
-
2xx:成功–表示请求已被成功接收、理解、接受。
-
3xx:重定向–要完成请求必须进行更进一步的操作。
-
4xx:客户端错误–请求有语法错误或请求无法实现。
-
5xx:服务器端错误–服务器未能实现合法的请求。
平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500(分别表示什么请自行查找)。
响应头:主要由Cache-Control、 Connection、Date、Pragma、server等组成。
响应报文:服务器返回给浏览器的文本信息。主要有html、css、js、图片等组成
五、浏览器解析渲染页面
浏览器渲染机制:
(1)浏览器的HTML解析器会将HTML文件解析成一棵DOM树,DOM树的构建是一个深度遍历的过程,当前节点的所有子节点都构建完成后,才会去构建当前节点的下一个兄弟节点。
(2)解析CSS文件构建CSSOM树
(3)根据DOM树(存储节点信息)和CSSOM树(存储节点渲染信息)构建渲染树,一些像head或display:none这些没必要放在渲染树中了。这棵树中包含了页面所有可见元素及其渲染信息。
(4)布局:渲染树生成后,浏览器根据渲染树中的信息,结合设备的屏幕信息,计算每个元素的位置和尺寸。
(5)渲染:得到了渲染树及其节点的布局信息,浏览器便可以将最终的页面渲染到屏幕上。
这个过程涉及两个概念:reflow(回流)和repain(重绘)
Reflow,也称作Layout,中文叫回流,一般意味着元素的内容、结构、位置或尺寸发生了变化,需要重新计算样式和渲染树,这个过程称为Reflow。
Repaint,中文重绘,意味着元素发生的改变只是影响了元素的一些外观之类的时候(例如,背景色,边框颜色,文字颜色等),此时只需要应用新样式绘制这个元素就OK了,这个过程称为Repaint。
优化:
(1)简化DOM结构,减少DOM树和渲染树构建成本;
(2)JS放在底部,CSS放在顶部
(3)减少DOM相关操作,如使用DocumentFragment、修改class name而不是style、减少重排和重绘操作