从url到页面展示

153 阅读4分钟

从输入url到页面展示主要经过哪些步骤呢?

大致步骤如下

  • 1.输入网址
  • 2.缓存解析
  • 3.域名解析
  • 4.tcp连接
  • 5.客户端发送HTTP请求
  • 6.客户端接收响应
  • 7.构建DOM树
  • 8.构建CSSOM树
  • 9.构建render树
  • 10.断开tcp连接

一:输入网址

在浏览器地址栏输入网址。

二:缓存解析

构建请求完毕后会开始查找是否存在强缓存,如果没有,则进行下一步,如果有的话就会去强缓存里面寻找资源,强缓存是通过Cache-Control进行控制,通过设置Cache-Control的Max-Age字段可以设置缓存有效期,在这个有效期内不会发送HTTP请求。

对比缓存通过HTTP的last-modified,Etag字段进行判断。

last-modified是第一次请求资源时,服务器返回的字段,表示最后一次更新的时间。下一次浏览器请求资源时就发送if-modified-since字段。服务器用本地Last-modified时间与if-modified-since时间比较,如果不一致则认为缓存已过期并返回新资源给浏览器;如果时间一致则发送304状态码,让浏览器继续使用缓存。

  Etag:资源的实体标识(哈希字符串),当资源内容更新时,Etag会改变。服务器会判断Etag是否发生变化,如果变化则返回新资源,否则返回304。

三: 域名解析

如果没有强缓存的话,我们会通过DNS域名系统来将网址解析成IP地址。

四:tcp连接

通过第三步取得的服务器的IP地址,浏览器和服务器就要进行TCP三次握手,浏览器第一次发送SYN并进入SYN-SENT状态,表明有发送消息的能力,服务器收到浏览器的请求后会发送SYN和ACK,这是第二次握手,浏览器收到服务器返回的报文后,会继续向服务器发送确认信息,表示自己已经收到服务器传来的内容,从而证明自己有发送、接收信息的能力。

为什么不是两次握手?两次握手无法证明浏览器有接收信息的能力,为什么不是四次握手?如果你的想话,你甚至可以100次握手,但实际上三次握手已经证明了客户端有能力进行链接。最后双方都进入ESTABLISHED状态。

五:客户端发送HTTP请求

浏览器开始构建请求行,请求行由三部分组成请求方式、请求URL以及HTTP版本号。

六:客户端接收响应

 服务器在收到浏览器发送的HTTP请求之后,会将收到的HTTP报文封装成HTTP的Request对象,并通过不同的Web服务器进行处理,处理完的结果以HTTP的Response对象返回,主要包括状态码,响应头,响应报文三个部分。  

七:构建DOM树

  • 由于浏览器无法直接对HTML解析,首先会创建以document对象为根节点的多叉树,紧接着会调用两个算法进行解析,分别是标记化算法和建树算法。
  • 标记化算法是将HTML文本解析成对应的HTML标记,并且保存起来供建树算法使用。
  • 建树算法将上一步的HTML标记解析成DOM对象

八:构建CSSOM树

  • 浏览器依然无法解析CSS,所以要先格式化CSS,将其转为styleSheets对象,并标准化样式属性,最后计算出每个节点的样式并挂载到window.getComputedStyle上面。
  • head标签和display:none的内容不会渲染上去。
  • 拿到了DOM树和DOM样式后,遍历DOM树,并将每个节点添加到布局树(Layout tree)上,以便于确定每个节点的位置。

九:构建render树

创建完布局树后,会针对一些特定的场景创建图层树,一般情况下,图层树是属于父亲节点的图层,如果想要成为单独的图层那么得经过显式合成和隐式合成,很简单的讲下:

  • 显式合成:具有层叠上下文特点以及需要裁剪。
  • 隐式合成:当层叠等级较低的情况下,使用z-index进行提升,就会形成单独的图层,不过可能会引起层爆炸另外,每个图层重绘的时候不会影响到其他的图层。

十:断开tcp连接

通过四次挥手关闭连接(FIN ACK, ACK, FIN ACK, ACK)。

  • 第一次挥手是浏览器发完数据后,发送FIN请求断开连接。
  • 第二次挥手是服务器发送ACK表示同意,如果在这一次服务器也发送FIN请求断开连接似乎也没有不妥,但考虑到服务器可能还有数据要发送,所以服务器发送FIN应该放在第三次挥手中。
  • 这样浏览器需要返回ACK表示同意,也就是第四次挥手。
参考资料:

url展示过程

从输入URL到页面加载的全过程