web 页面的关键渲染路径
# web 页面的关键渲染路径
总体来说有几个过程:
- DNS 解析:将域名解析成 IP 地址
- TCP 链接:三次握手
- 发送 HTTP 请求
- 服务端处理请求并返回 HTTP 报文
- 浏览器解析并渲染页面
- 断开连接:四次挥手
# 一、DNS 解析
在浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到对应的服务器,而是要通过 IP 地址 DNS 是一个网络服务器
# 1.1 IP 地址
IP 地址是指互联网协议地址,是 IP Address 的缩写
域名就相当于 IP 地址乔装打扮的伪装者,带着一副面具。它的作用就是便于记忆和沟通的一组服务器的地址。
# 1.2 域名解析
DNS 协议提供通过域名查找 IP 地址,或逆向从 IP 地址反查域名的服务。
DNS 是一个网络服务器,我们的域名解析简单来说就是在 DNS 上记录一条信息记录。
# dns 过程
- 浏览器检查自身有没有解析过这个域名 对应的 IP 地址
- 没有命中,检查操作系统 有没有已解析的
- 也没有命中,请求 本地域名服务器 来解析,一般在你城市的某个角落
- 如果还没有命中,直接到 root server 域名服务器请求解析
- 根域名返回给 本地 dns 一个 所查询域 的主域名服务器地址
- 本地 dns 请求 上一步的 主域名服务器
- 主域名服务器返回 name server (网站注册的域名服务器)
- name server 根据映射关系找到 IP ,返回给本地 dns
- 本地域名服务器缓存这个 域名 和 IP
- 本地域名服务器 把结果返回给用户,增加到本地缓存
# 1.3 浏览器如何通过域名去查询 URL 对应的 IP
- 浏览器缓存
- 操作系统缓存
- 路由缓存
- ISP 的 DNS 服务器
- 根服务器:ISP 的 DNS 服务器还找不到的话,它就会向根服务器发出请求,进行递归查询
# 1.4 解析过程
- 浏览器通过向 DNS 服务器发送域名,DNS 服务器查询到与域名相对应的 IP 地址,然后返回给浏览器,
- 浏览器再将 IP 地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器
# 二、 TCP 三次握手
客户端发送数据之前会发起 TCP 三次握手
以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。
# 2.1 握手过程
- 客户端:发送一个带 SYN=1,Seq=X 的数据包到服务器端口
- 服务器:发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息
- 客户端:再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”
# 2.2 为啥需要三次握手
为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误
# 三、发送 HTTP 请求
TCP 三次握手结束后,开始发送 HTTP 请求报文
请求报文由请求行、请求头、请求体三个部分组成
# 3.1 请求行
请求行包含请求方法、URL、协议版本
- 请求方法包含 8 种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。
- URL 即请求地址,由 <协议>://<主机>:<端口>/<路径>?<参数> 组成
- 协议版本即 http 版本号
# 3.2 请求头
请求头包含请求的附加信息,由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔
请求头部通知服务器有关于客户端请求的信息。它包含许多有关的客户端环境和请求正文的有用信息。其中比如:Host,表示主机名,虚拟主机;
# 3.3 请求体
请求体,可以承载多个请求参数的数据,包含回车符、换行符和请求数据,并不是所有请求都具有请求数据
# 四、 服务器处理请求并返回 HTTP 报文
# 4.1 MVC 模式
MVC 是一个设计模式,将应用程序分成三个核心部件:
- 视图(view):它是提供给用户的操作界面,是程序的外壳。
- 模型(model):模型主要负责数据交互;
- 控制器(controller):它负责根据用户从"视图层"输入的指令,选取"模型层"中的数据,然后对其进行相应的操作,产生最终结果
# 4.2 后台处理阶段
- 首先浏览器发送过来的请求先经过控制器,控制器进行逻辑处理和请求分发,
- 接着会调用模型,这一阶段模型会获取 redis db 以及 MySQL 的数据,获取数据后将渲染好的页面,响应信息会以响应报文的形式返回给客户端,
- 最后浏览器通过渲染引擎将网页呈现在用户面前。
# 4.3 响应报文
响应报文由响应行(request line)、响应头部(header)、响应主体三个部分组成。
# 1. 响应行
包含:协议版本,状态码,状态码描述
状态码规则如下:
1xx:指示信息--表示请求已接收,继续处理。
2xx:成功--表示请求已被成功接收、理解、接受。
3xx:重定向--要完成请求必须进行更进一步的操作。
4xx:客户端错误--请求有语法错误或请求无法实现。
5xx:服务器端错误--服务器未能实现合法的请求。
2
3
4
5
6
# 2. 响应头部
包含响应报文的附加信息,由 名/值 对组成
# 3. 响应主体
包含回车符、换行符和响应返回数据,并不是所有响应报文都有响应数据
# 五、浏览器解析渲染页面
浏览器拿到响应文本 HTML 后,接下来介绍下浏览器渲染机制
浏览器解析渲染页面分为一下五个步骤:
- 根据 HTML 解析出 DOM 树
- 根据 CSS 解析生成 CSS 规则树
- 结合 DOM 树和 CSS 规则树,生成渲染树
- 根据渲染树计算每一个节点的信息
- 根据计算好的信息绘制页面
# 5.1 根据 HTML 解析 DOM 树
- 根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点
- 在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。
# 5.2 根据 CSS 解析生成 CSS 规则树
- 解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪
- 浏览器在 CSS 规则树生成之前不会进行渲染
# 5.3 render 树:结合 DOM 树和 CSS 规则树,生成渲染树
- DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树
- 精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度
# 5.4 布局:根据渲染树计算每一个节点的信息
- 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸
- 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染
# 5.5 绘制:根据计算好的信息绘制页面
- 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上
- 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘
- 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染
# 六、 断开连接
当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。
- 客户端:向服务器发送报文,Fin、Ack、Seq,表示已经没有数据传输了。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)
- 服务端:向客户端发送报文,Ack、Seq,表示同意关闭请求,进入 FIN_WAIT_2 状态(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)
- 服务器发起:向客户端发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)
- 客户端:向服务端发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)