在浏览器地址栏输入url到页面展示出东西都发生了什么

 

在浏览器地址栏输入url到页面展示出东西都发生了什么

​ 看到这个问题,第一反应,这个问题好像已经被面试官问的烂大街了,网上随便一搜,全是,有什么好记录的。我开始也是这么想的,以为被问烂大街的东西不会被问到了,结果上周出去面试,最没想到的是居然被问到了,啊难受。

吐血

这个问题当时怎么回答的就不写了,反正就是粗略的答了一下,细节也不是很清楚, 所以记录一下。为下次面试做准备,Fighting!!!

以下是正文

  1. 在浏览器地址栏中输入url并按下回车键

  2. 浏览器构建 请求行, 构建好以后,浏览器进程会通过进程间通信(IPC)将url请求发送至网络进程,网络进程接收到url请求以后会发起真正的url请求流程

    // 请求方法  请求URI HTTP协议版本
    GET /index.html HTTP/1.1   // 请求行内容
    
  3. 首先检查浏览器是否缓存了当前请求的资源, 如果有,会拦截请求, 返回该资源的副本, 并直接结束请求

  4. 如果没有缓存,会直接进入网络请求流程

    1. 获取IP地址和端口。浏览器会请求DNS返回域名对应的IP, DNS服务器也提供数据缓存服务,如果请求的是HTTPS请求, 还需要进行TSL连接。如果没有指明端口号,HTTP默认是80, HTTPS默认是443

    2. 等待TCP连接。 Chrome有个机制,同一域名同时最多只能建立6个TCP连接,如果同一域名下同时有8个 请求发生,则后面2个请求会进入排队等待状态,直到进行中的请求完成,如果同时少于6个,则直接进入下一步

    3. 建立TCP连接(TCP三次握手

    4. 发送HTTP请求,浏览器会向服务器发送请求行, 包括 请求方法请求URIHTTP协议版本,如果 是POST方法,还需要将准备的数据通过请求体发送。之后,浏览器还要以请求头形式发送其他一些信 息,把浏览器的一些基础信息告诉服务器, 包括浏览器所使用的操作系统、浏览器内核等信息,以及当 前请求的域名信息、浏览器的Cookie信息等等

    5. 服务器对接收到的请求进行处理并准备相应的内容

    6. 服务器返回请求, 首先服务器会返回响应行, 包括 HTTP协议版本状态码状态描述 等, 服务器会通 过状态码来告诉浏览器它的处理结果

      HTTP/1.1 200 OK
    

    ​ 随后, 服务器会随同响应向浏览器发送响应头,响应头包含了服务器自身的一些信息,比如服务器生成返 回数据的时间,返回的数据类型,以及服务器要在客户端保存的Cookie等信息。发送完响应头,服务器就 可以继续发送响应体数据了。

    1. 断开连接(TCP四次挥手)。但是, 如果浏览器或者服务器在其头部信息中加入了
       Connection: Keep-Alive
    

    ​ 那么TCP连接在发送后仍然保持打开状态, 这样浏览器就可以继续通过同一个TCP连接发送请求。保持 TCP连接可以省去下次请求时需要建立连接的时间, 提升资源加载速度

    1. 重定向。如果服务器返回的状态码是 301302, 这就是要告诉浏览器我要重定向到另外一个网址,重定 向的网址包含在响应头的Location字段中, 之后重复步骤4。 如果是200,表示浏览器可以继续处理该请 求。

    2. 响应数据类型处理。浏览器会根据响应头中的Content-Type字段来处理服务器返回的数据,Content-type字段的值被判断为下载类型, 那么该请求会被提交给浏览器的下载管理器,同时该URL请求的导航流程就此结束,如果是HTML,那么浏览器则会继续进行导航流程

  5. 准备渲染进程。默认情况下,Chrome浏览器会为每个页面分配一个渲染进程,即每打开一个页面就会创建一个新的渲染进程。但是, 如果从一个页面打开了另外一个新页面,且新页面和当前页面属于同一站点,即根域名协议相同,那么新页面就会复用父页面的渲染进程。

  6. 提交文档。“文档”指URL请求的响应体数据。提交文档的消息是由浏览器进程发出的,渲染进程接收到提交文档的消息后,会和网络进程建立传输数据的“管道”, 等文档数据传输完成之后,渲染进程会返回确认提交的信息给浏览器进程。 浏览器进程在收到 确认提交 的消息后, 会更新浏览器界面状态, 包括安全状态, 地址栏的URL,前进后退的历史状态,并更新web页面。

  7. 渲染阶段。

    1. 构建DOM树🌲。浏览器无法直接理解和使用HTML,所以需要将HTML转换成浏览器能够理解的结构——DOM树。直接在控制台中输入document就可以查看DOM树

    2. 样式计算。主要目的是为了计算出DOM节点中每个元素的样式, 大致可分为以下三个步骤

      1. 把css转换成浏览器能够理解的结构,浏览器会将css文本转化为styleSheets, 在控制台中打印document.styleSheets查看

      2. 转换样式表中的属性值,使其标准化。例如

        body { font-size: 2em} —————> body { font-size: 32px}
        
      3. 根据css的继承层叠规则计算出DOM树中每个节点的具体样式

    3. 布局阶段

      1. 创建布局树,将DOM树中所有可见的元素添加到布局树中
      2. 布局计算, 计算布局树节点的位置坐标
    4. 分层。 渲染引擎需要为特定的节点生成专用的图层,并生成一颗对应的图层树。但是并不是每个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。

      提升为单独的图层的条件

      • 拥有层叠上下文属性的元素会被提升为单独的一层(position, z-index, filter, opacity)
      • 需要裁剪的地方也会被创建为图层
    5. 图层绘制。会把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表

    6. 栅格化操作——将图块转换成位图。真正的绘制操作其实是由渲染引擎中的合成线程来完成的,当图层的绘制列表准备好以后,主线程会把该绘制列表提交给合成线程。然后合成线程会将图层划分为图块,图块大小通常是256x256或者512x512,之后合成线程会按照视口附件的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。

    7. 合成和显示。 一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”, 然后将该命令提交给浏览器进程。浏览器进程中有一个viz组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,将其页面内容绘制到内存中,最后再将内存中的内容显示到屏幕上。

    整个流程终于完了,至此,一个漂亮的页面就会展示在你的面前。^_^