经典问题:地址栏敲下回车,发生的事情(有坑)

地址栏内容检测

当用户在地址栏输入内容,会先判断输入的内容是否符合url规则。如果用户输入的是文字,就会调用浏览器默认的搜索引擎,把这个文字作为搜索的关键字来搜索。如果输入的内容是符合url规则的,就作为请求的路径,如果是,但是没有写全,就会补全。

缓存的检测

在准备发请求之前,先查看有没有缓存

很多地方都有缓存

首先是看浏览器中是否有缓存,浏览器有一个用来缓存的线程service worker,如果没有找到就进行下一步,(虽然可能是从其他地方找到的缓存,但是浏览器会显示是从service worker获得的缓存)

然后是从内存中查找,内存的大小有限,能够存储的内容也不多,内存读取数据更快,但持续时间短,页面关闭缓存就被释放了

然后再从硬盘中查找,硬盘的存储空间就比内存的存储空间大的多,绝大多数缓存都是从这里获取的 (我个人以为强缓存就是存在硬盘中的)

当用户第一次发送了请求之后,就会有缓存,页面缓存也好,DNS缓存,服务器在响应的时候设置了响应头中携带的信息

强缓存:设置了强缓存,只要没有过期,就可以直接使用,不用发请求

    http1.1  cache-control: max-age 设置缓存的过期时长

    http1.0 expires 设置缓存在什么时候过期,(这样设置不是太好,有可能浏览器和服务器的时间不同)

强缓存过期之后,就会验证协商缓存

协商缓存:要先发验证请求,看页面是否有更新,如果有更新就发新请求,如果没有更新,服务器就返回304,表示静态资源没有更新

     http1.1 If-None-Match/ E-tag 给每一个版本设置标记,如果页面内容有变化,就有新的tag,在看页面是否变化的时候,就直接看tag是否相同

     http1.0 If-Modified-since/ Last-Modified 记录每个版本修改的时间,请求的时候比较页面时间是否在

如果我们按下ctrl + f5,就会设置cache-control:no-cache,pragma:no-cache,让浏览器不经过本地缓存校验,直接发起请求

DNS解析

缓存没有找到,就要进行DNS解析,通过域名找到对应的IP地址

DNS也有缓存,先找本地的缓存hosts文件中,如果本地没有缓存,就要进行DNS解析,客户端向本地DNS服务器发送请求,这个请求是一个UDP方式的,这样更快。如果本地DNS服务器有就返回,如果没有,本地DNS服务器就作为客户,向其他根域名服务器发请求,如果找到就返回。DNS域名解析是一个迭代,递归的过程。

建立TCP连接

排队等待 

如果是http2.0就不存在排队等待的问题,但是如果是http1.x可能就需要排队等待

因为http1.0是一个连接发送一次请求,一个域名最多建立6个TCP连接

  http1.1虽然是个长连接,但是还是要等前面的发送完了才能发送后面的

三次握手

是建立TCP连接的过程

首先客户端向服务器发送一个建立连接的请求

然后服务端收到之后,就返回一个确认收到的报文

客户端收到这个确认报文之后,就向服务端发送一个收到确认的确认报文

为什么要有三次握手,不是两次,或者四次呢?

因为如果当客户端发出建立连接的请求阻塞在网络中的时候,客户端就会重新发建立连接的请求。当连接已经释放之后,之前阻塞在网络中的建立连接请求才到达,此时,服务器会以为客户端又重新请求建立连接,返回一个确认报文,但是客户端并没有请求建立连接,会忽略这的确认报文。如果是两次握手的话,服务器就以为建立了连接,但是客户端根本就没有发请求,会导致服务器等待,浪费服务器资源。可以是四次握手,但是没有必要多花一次来浪费资源。

发送请求,返回响应

四次挥手

当客户端没有数据发送给服务器之后,就发送一个释放连接的请求,表示客户端已经没有数据发给服务器了。

服务器收到之后就返回一个收到的确认报文。服务端不会马上返回确认报文,要等到服务端把要发送的所有数据发送完之后

客户端等待,服务器的所有数据发送完成之后,就向客户端再发送一个释放连接的报文

客户端收到之后向服务器发送收到的确认报文。对于服务器来说已经结束了

但是客户端还要再等待2MSL的时间,才改变状态为close

为什么要等待?

确保服务器正常收到确认报文,如果没收到的话,服务器会有一个请求重传。只要2MSL时间之内没有收到确认重传,就说明一切正常

为什么是2MSL?

片段在网络中最大的存活时间就是MSL,2MSL就是一个往返的时间,如果经历了2MSL都还没有收到确认

此时浏览器已经收到了响应数据,接下来就是浏览器的行为了

 

文件类型判断

浏览器请求的内容可能不是html等类型,也可能是下载类型。如果是下载内型,浏览器就会开启一个下载线程,用来进行文件下载

如果类型是Html,就进行页面的渲染

页面渲染

DOM树生成

浏览器收到html文档之后,开始解析,但是他不认识html代码,所以要将html解析成token,对于html来说,分为tag token和 text token

利用栈来判断各节点之间的嵌套关系,如果遇到start tag token就入栈,然后在DOM树中添加一个DOM节点。如果遇到的是text token就直接在DOM树中添加一个文本节点。如果遇到的是 end tag token,就看栈顶是否是对应的start tag token 如果是,start tag token就出栈,表示这个DOM节点解析完成。

cssOM树的生成

css代码也是浏览器不认识的,所以也需要解析,将css解析成stylesheets,这个过程是将css属性值标准化,例如将rem->px等,stylesheets是可以通过脚本document.stylesheets获取的

布局树的生成

DOM树中的所有节点并不是都要渲染到页面,需要DOM树和CSSOM树的结合,才知道哪些节点是会渲染到页面上的,就有了布局树的生成

图层树的生成

根据每个节点的特点,可以区分出某些节点是在一个图层,就有了图层树的生成

图层树中的每个节点就是一个图层

栅格化

图层树生成之后,就根据图层生成绘制指令。根据绘制指令按顺序开始绘制。因为图层很大,就会把图层分成多个图块,每个图层就是一张图片。

栅格化的过程就是图块转化成位图的过程。会先从接近视口的地方开始转化,当所有的位图都生成完之后,会发送一个绘制指令

合成和绘制

最后将几张位图合成为一张图片,最后发送到显卡的后缓冲区中。显示到页面。

显示器显示图像

显示器的刷新频率1秒60次,就是显示器每秒钟要读取显卡前缓冲区的内容60次,并显示到页面。

显卡的作用是生成图像,新生成的图像就写入后缓冲区中,系统会交换前缓冲区和后缓冲区的内容,这样显示器每次读取的都是新的内容

显示器刷新的频率要和显卡更新的频率一致

 

如若有错,还请指正。

 三次握手和四次挥手还要再完善

posted @ 2020-08-02 10:52  kkkllo  阅读(224)  评论(0)    收藏  举报