问题:输入URL地址到浏览器完成渲染的整个过程

183 阅读8分钟

简单版

1.浏览器地址栏输入URL地址,回车

2.浏览器查找当前URL是否存在缓存,并比较缓存是否过期

3.DNS解析URL对应的IP

4.根据IP建立TCP连接(三次握手)

5.发送HTTP请求

6.服务器处理请求,浏览器接受HTTP响应

7.浏览器解析并渲染页面

8.关闭TCP连接(四次挥手)

高级版

  • 浏览器输入URL 输入URL,按下回车,就进入应用层往下走,浏览器会开一个线程处理,对URL解析

  • 应用层DNS解析域名 DNS解析就是对域名或IP解析

    • 首先查看浏览器DNS缓存
    • 没有就查询计算机本地DNS缓存
    • 还没有就询问递归式DNS服务器
  • 应用层客户端发送HTTP请求 IP地址有了,客户端就会发送一个HTTP请求,HTTP请求分为请求报头和请求主体

    • 请求报头包含:请求方法(POST,GET等),协议版本号,请求头部方法(Accept、Cache-Control...)
    • 请求主体:客户端发送给服务器或者服务器返回给客户端的内容
  • 传输层TCP传输报文 客户端在传输层开始和服务器通过三次握手建立TCP/IP连接

  • 网络层IP协议查询MAC地址 网络层IP协议会查询MAC地址进行数据包的传输

  • 数据到达数据链路层 找到对方的MAC地址后,会将数据发送到数据链路层传输,到此客户端发送请求阶段就结束了

  • 服务器接收数据 服务器在数据链路层接收到数据包,在通过相反的方式将数据一层一层的还原回应用层 请求到后台服务器,会有验证(安全验证、跨域验证等),验证未通过就直接返回相应的HTTP报文,验证通过,就执行对应的操作 如果浏览器访问过,且缓存上有对应的资源,就会与服务器最后修改的时间对比,一致就返回304,告诉浏览器可使用本地缓存

  • 服务器响应请求 服务器接收到客户端发送的HTTP请求后,会查找客户端请求的资源,并返回响应报文。

  • 服务器返回相应文件 请求成功后,服务器会返回相应的网页,浏览器接收到响应成功的报文后便开始下载网页,网络通信结束

  • 解析HTML构建DOM Tree

  • 解析CSS构建CSSOM Tree

  • 构建渲染树(Render Tree) 将DOM树和CSSOM树合并成渲染树,渲染树只包含渲染网页所需的节点,然后用于计算每个可见元素的布局,并输出给绘制流程,将像素渲染在屏幕上。

  • 布局

  • 绘制

  • 合成

简洁回答

  • 首先,客户端浏览器输入URL,由于是域名,应用层DNS开始解析域名

  • 接着,应用层客户端发送一个HTTP请求,把拿到的应用层HTTP请求报文数据分割编号,为了方便安全的传输,传输层会通过TCP三次握手建立TCP/IP链接

  • 建立连接后 网络层 IP协议会查询服务器 MAC地址 也就是物理地址进行数据包的传输

  • 找到对方的 MAC地址 后,将数据发送到 数据链路层传输,到此客户端发送请求阶段结束

  • 接收端的服务器在 数据链路层 接收到数据包,再通过相反的方式将数据一层一层的还原回 应用层

  • 服务器接收到客户端发送的HTTP请求后,会查找客户端请求的资源,并返回响应报文

  • 请求成功后,服务器会返回相应的网页,浏览器接收到响应成功的报文后便开始下载网页,至此,网络通信结束

  • 浏览器拿到网页文件后,首先根据顶部定义的DTD类型进行对应解析方式,网页解析会交给内部GUI渲染线程处理

  • 接着构建DOM树和CSSOM树,过程中,如果遇到节点是 JS ,就会调用 JS引擎 对 JS代码进行解释执行,此时由于 JS引擎GUI渲染线程 互斥,GUI渲染线程 会被挂起,渲染过程停止,如果 JS 代码的运行中对DOM树进行了修改,那么DOM构建要从新开始,然后DOM树和CSSOM树构建为渲染树

  • 然后进入布局阶段,计算渲染树节点在设备视口内的确切位置和大小

  • 再接着将渲染树中每个节点转换成屏幕上的实际像素,也就是绘制阶段

  • 最后的合成阶段浏览器会将各层信息发送给GPU,GPU将各层合成,显示在屏幕上

详细解析

针对第二项解析

1.HTTP缓存:强缓存 2.HTTP缓存:协商缓存

针对三次握手

  • 1.第一次握手:

客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;(由浏览器发起,告诉服务器我要发送请求了)

  • 2. 第二次握手:

服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;(由服务器发起,告诉浏览器我准备接受了,你赶快发送)

  • 3. 第三次握手:

客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。(由浏览器发送,告诉服务器,我马上发,准备接受)

为啥需要三次握手??

三次握手”的目的是为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误。

三次握手过程中可以携带数据么?

第一次、第二次握手不可以携带数据,因为一握、二握还没有建立连接,会让服务器容易受到攻击。 三次握手,客户端处于ESTABLISHED(已建立连接状态),可以携带数据

发送HTTP请求

发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由请求行,请求报头,请求正文组成

服务器处理请求并返回HTTP报文

状态码、响应报头、响应报文

浏览器解析渲染页面

1.解析HTML形成DOM树 2.解析CSS形成CSSOM树 3.合并DOM树和CSSOM树形成渲染树 4.浏览器开始渲染并绘制页面(回流和重绘)

针对四次挥手

1.第一次挥手:

客户端发送一个FIN,用来关闭客户端到服务端的数据传送,客户端进入FIN_WAIT_1(终止等待1)状态。

2.第二次挥手:

服务端收到FIN包后,发送一个ACK给客户端,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE-WAIT状态。客户端就进入FIN-WAIT-2(终止等待2)状态,等待服务器发送连接释放报文。

3.第三次挥手:

服务端发送一个FIN,用来关闭服务端到客户端的数据传送,服务端就进入了LAST_ACK(最后确认)状态,等待客户端的确认。

4.第四次挥手:

客户端收到FIN后,客户端进入TIME_WAIT状态,接着发送一个ACK给服务器,确认序号为收到序号+1,服务端进入CLOSED状态,完成四次挥手。

简单理解记忆:(FIN:finish,ACK:acknowledge)

  • 客户端------FIN------》服务端
  • 服务端------ACK------》客户端
  • 服务端------FIN------》客户端
  • 客户端------ACK------》服务端

总结

由这个问题可以牵扯很多知识点

1:浏览器缓存 2:HTTP 3:回流和重绘 4:JS事件循环 5:垃圾处理机制 6:性能优化

总结:

  • URL检测:判断是否是合法URL,域名补全,转义字符编码
  • 浏览器本地缓存这个资源,直接讲数据转发给浏览器进程,没有缓存,下一步,DNS解析域名
  • DNS解析域名
  • TCP三次握手
  • 准备请求(请求头,请求体)
  • 发送请求,get请求
  • 服务器处理请求,查询数据库
  • 服务器响应
  • 浏览器收到响应头(set-cookie,content-type,缓存,状态码,connection,keep-alive)
  • 收响应体
  • 渲染
    • 解析(预处理线程,资源加载,async defer, prefetch. repload)
    • 生成DOM树+CSSOM树
    • 样式计算
    • Layout布局
    • layer分层
    • paint绘制
  • 主线程结束,
  • 根据情况决定是是否断开连接:四次挥手