在浏览器地址栏输入url到页面展示出东西都发生了什么
看到这个问题,第一反应,这个问题好像已经被面试官问的烂大街了,网上随便一搜,全是,有什么好记录的。我开始也是这么想的,以为被问烂大街的东西不会被问到了,结果上周出去面试,最没想到的是居然被问到了,啊难受。
这个问题当时怎么回答的就不写了,反正就是粗略的答了一下,细节也不是很清楚, 所以记录一下。为下次面试做准备,Fighting!!!
以下是正文
-
在浏览器地址栏中输入url并按下回车键
-
浏览器构建 请求行, 构建好以后,浏览器进程会通过进程间通信(IPC)将url请求发送至网络进程,网络进程接收到url请求以后会发起真正的url请求流程
// 请求方法 请求URI HTTP协议版本 GET /index.html HTTP/1.1 // 请求行内容
-
首先检查浏览器是否缓存了当前请求的资源, 如果有,会拦截请求, 返回该资源的副本, 并直接结束请求
-
如果没有缓存,会直接进入网络请求流程
-
获取IP地址和端口。浏览器会请求DNS返回域名对应的IP, DNS服务器也提供数据缓存服务,如果请求的是HTTPS请求, 还需要进行TSL连接。如果没有指明端口号,HTTP默认是80, HTTPS默认是443
-
等待TCP连接。 Chrome有个机制,同一域名同时最多只能建立6个TCP连接,如果同一域名下同时有8个 请求发生,则后面2个请求会进入排队等待状态,直到进行中的请求完成,如果同时少于6个,则直接进入下一步
-
建立TCP连接(TCP三次握手)
-
发送HTTP请求,浏览器会向服务器发送请求行, 包括 请求方法、 请求URI、HTTP协议版本,如果 是
POST
方法,还需要将准备的数据通过请求体发送。之后,浏览器还要以请求头形式发送其他一些信 息,把浏览器的一些基础信息告诉服务器, 包括浏览器所使用的操作系统、浏览器内核等信息,以及当 前请求的域名信息、浏览器的Cookie信息等等 -
服务器对接收到的请求进行处理并准备相应的内容
-
服务器返回请求, 首先服务器会返回响应行, 包括 HTTP协议版本、状态码、状态描述 等, 服务器会通 过状态码来告诉浏览器它的处理结果
HTTP/1.1 200 OK
随后, 服务器会随同响应向浏览器发送响应头,响应头包含了服务器自身的一些信息,比如服务器生成返 回数据的时间,返回的数据类型,以及服务器要在客户端保存的Cookie等信息。发送完响应头,服务器就 可以继续发送响应体数据了。
- 断开连接(TCP四次挥手)。但是, 如果浏览器或者服务器在其头部信息中加入了
Connection: Keep-Alive
那么TCP连接在发送后仍然保持打开状态, 这样浏览器就可以继续通过同一个TCP连接发送请求。保持 TCP连接可以省去下次请求时需要建立连接的时间, 提升资源加载速度
-
重定向。如果服务器返回的状态码是 301或302, 这就是要告诉浏览器我要重定向到另外一个网址,重定 向的网址包含在响应头的Location字段中, 之后重复步骤4。 如果是200,表示浏览器可以继续处理该请 求。
-
响应数据类型处理。浏览器会根据响应头中的
Content-Type
字段来处理服务器返回的数据,Content-type
字段的值被判断为下载类型, 那么该请求会被提交给浏览器的下载管理器,同时该URL请求的导航流程就此结束,如果是HTML,那么浏览器则会继续进行导航流程
-
-
准备渲染进程。默认情况下,Chrome浏览器会为每个页面分配一个渲染进程,即每打开一个页面就会创建一个新的渲染进程。但是, 如果从一个页面打开了另外一个新页面,且新页面和当前页面属于同一站点,即根域名和协议相同,那么新页面就会复用父页面的渲染进程。
-
提交文档。“文档”指URL请求的响应体数据。提交文档的消息是由浏览器进程发出的,渲染进程接收到提交文档的消息后,会和网络进程建立传输数据的“管道”, 等文档数据传输完成之后,渲染进程会返回确认提交的信息给浏览器进程。 浏览器进程在收到 确认提交 的消息后, 会更新浏览器界面状态, 包括安全状态, 地址栏的URL,前进后退的历史状态,并更新web页面。
-
渲染阶段。
-
构建DOM树🌲。浏览器无法直接理解和使用HTML,所以需要将HTML转换成浏览器能够理解的结构——DOM树。直接在控制台中输入
document
就可以查看DOM树 -
样式计算。主要目的是为了计算出DOM节点中每个元素的样式, 大致可分为以下三个步骤
-
把css转换成浏览器能够理解的结构,浏览器会将css文本转化为styleSheets, 在控制台中打印
document.styleSheets
查看 -
转换样式表中的属性值,使其标准化。例如
body { font-size: 2em} —————> body { font-size: 32px}
-
根据css的继承和层叠规则计算出DOM树中每个节点的具体样式
-
-
布局阶段
- 创建布局树,将DOM树中所有可见的元素添加到布局树中
- 布局计算, 计算布局树节点的位置坐标
-
分层。 渲染引擎需要为特定的节点生成专用的图层,并生成一颗对应的图层树。但是并不是每个节点都包含一个图层,如果一个节点没有对应的图层,那么这个节点就从属于父节点的图层。
提升为单独的图层的条件
- 拥有层叠上下文属性的元素会被提升为单独的一层(position, z-index, filter, opacity)
- 需要裁剪的地方也会被创建为图层
-
图层绘制。会把一个图层的绘制拆分成很多小的绘制指令,然后再把这些指令按照顺序组成一个待绘制列表
-
栅格化操作——将图块转换成位图。真正的绘制操作其实是由渲染引擎中的合成线程来完成的,当图层的绘制列表准备好以后,主线程会把该绘制列表提交给合成线程。然后合成线程会将图层划分为图块,图块大小通常是256x256或者512x512,之后合成线程会按照视口附件的图块来优先生成位图,实际生成位图的操作是由栅格化来执行的。
-
合成和显示。 一旦所有图块都被光栅化,合成线程就会生成一个绘制图块的命令——“DrawQuad”, 然后将该命令提交给浏览器进程。浏览器进程中有一个viz组件,用来接收合成线程发过来的DrawQuad命令,然后根据DrawQuad命令,将其页面内容绘制到内存中,最后再将内存中的内容显示到屏幕上。
整个流程终于完了,至此,一个漂亮的页面就会展示在你的面前。^_^
-