浏览器输入网址到渲染出页面

219 阅读8分钟

过程分为下方几个流程:

  • DNS解析:把域名解析成IP地址

  • TCP 建立连接:TCP三次握手

  • 发送HTTP请求

  • 服务器处理并响应报文

  • 浏览器解析并渲染页面

  • 断开连接:TCP 结束连接

相关知识点:

URL

DNS解析、IP地址

TCP建立连接、三次握手

服务器处理、HTTP请求、状态码

浏览器渲染

TCP连接结束

一、什么是URL?

URL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。

一般遵守下面的语法规则:

scheme://host.domain:port/path/filename

各部分解释如下:

  • scheme - 定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。

  • host - 定义域主机(http 的默认主机是 www,也叫服务器名)

  • domain - 定义因特网域名,比如 baodu.com(后缀结尾: .com 用于商业公司 .org 用于组织、协会等 .net 用于网络服务 .edu 用于教育机构 .gov. 用于政府部门 .mil 用于军事领域)

  • port - 定义主机上的端口号(http 的默认端口号是 80)

  • path - 定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)

  • filename - 定义文档/资源的名称

二、域名解析(DNS)

DNS解析过程就是通过网络查找哪台机器有你需要的资源的过程。

浏览器输入一个域名并不是真正意义上的去查找这个,而是去查找对应域名的IP地址。

域名只是一个别名,方便记忆。

向浏览器的缓存中查找;如果没有则进行下一步;

向系统缓存(本地的hosts文件)中查找;如果没有则进行下一步;

向路由器查询DNS缓存;如果没有则进行下一步;

向ISP(运营商)DNS缓存中查找(比如电信)如果没有则进行下一步;

向根域名服务器 => 顶级域名服务器中查找,同时缓存这个 IP 地址,下次就直接访问了。

eg:DNS解析过程

  1. 查找www.github.com;

  2. 访问客户端DNS缓存:「浏览器缓存 -> 系统缓存(host)-> 路由器缓存」,host可以通过ihost去修改。

  3. 访问 ISP DNS服务器(ISP,互联网服务提供商,有联通电信移动等。如果你是电信网络,则进入电信的 DNS 缓存服务器,以下简称本地),如果本地服务器有,则直接返回;如果没有,让本地 DNS 服务器去咨询查找。

  4. 本地去咨询 DNS 根服务器,DNS 根服务器发现是 .com 区域 管理的,告诉本地去咨询它。

  5. 本地去咨询 .com 顶级域名服务器,.com 顶级域名服务器不太清楚,告诉本地去咨询 github.com 主区域 的服务器。

  6. 本地去咨询 github.com 主域名服务器,github.com 域服务器查找到对应的 IP 地址,返回给本地。

  7. 本地服务器通知用户,github.com 对应的 IP 地址,同时缓存这个 IP 地址,下次就直接访问了。

三、TCP 三次握手

在客户端发送数据之前会发起 TCP 三次握手用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。

网上也有很多方便易解的过程,这里我直接引用:

  1. TCP 三次握手的过程如下:
  • 客户端发送一个带 SYN=1,Seq=X 的数据包到服务器端口(第一次握手,由浏览器发起,告诉服务器我要发送请求了)

  • 服务器发回一个带 SYN=1, ACK=X+1, Seq=Y 的响应包以示传达确认信息(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)

  • 客户端再回传一个带 ACK=Y+1, Seq=Z 的数据包,代表“握手结束”(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)

  1. 为啥需要三次握手? 谢希仁著《计算机网络》中讲“三次握手”的目的是**“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”**。

四、向服务器发送HTTP请求

建立TCP连接后,开始向Web服务器发送HTTP请求报文。

  • 请求方法包含 8 种:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。

  • URL 即请求地址,由 <协议>://<主机>:<端口>/<路径>?<参数> 组成

  • 协议版本即 http 版本号

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

服务器接受到请求后,对相应的请求作出相应的处理,处理完成后并作出相应的http 响应报文

** 响应行包含:协议版本,状态码,状态码描述 **

状态码规则如下:

  • 1xx:指示信息--表示请求已接收,继续处理。

  • 2xx:成功--表示请求已被成功接收、理解、接受。

  • 3xx:重定向--要完成请求必须进行更进一步的操作。

  • 4xx:客户端错误--请求有语法错误或请求无法实现。

  • 5xx:服务器端错误--服务器未能实现合法的请求。

六、浏览器解析渲染页面

不做过多解释,搬我觉得网上比较简单易懂的

浏览器拿到响应文本 HTML 后,接下来介绍下浏览器渲染机制

浏览器解析渲染页面分为一下五个步骤:

  • 根据 HTML 解析出 DOM 树

  • 根据 CSS 解析生成 CSS 规则树

  • 结合 DOM 树和 CSS 规则树,生成渲染树

  • 根据渲染树计算每一个节点的信息

  • 根据计算好的信息绘制页面

  • 根据 HTML 解析 DOM 树

  • 根据 HTML 的内容,将标签按照结构解析成为 DOM 树,DOM 树解析的过程是一个深度优先遍历。即先构建当前节点的所有子节点,再构建下一个兄弟节点。

  • 在读取 HTML 文档,构建 DOM 树的过程中,若遇到 script 标签,则 DOM 树的构建会暂停,直至脚本执行完毕。

  • 根据 CSS 解析生成 CSS 规则树

  • 解析 CSS 规则树时 js 执行将暂停,直至 CSS 规则树就绪。

  • 浏览器在 CSS 规则树生成之前不会进行渲染。

  • 结合 DOM 树和 CSS 规则树,生成渲染树

  • DOM 树和 CSS 规则树全部准备好了以后,浏览器才会开始构建渲染树。

  • 精简 CSS 并可以加快 CSS 规则树的构建,从而加快页面相应速度。

  • 根据渲染树计算每一个节点的信息(布局)

  • 布局:通过渲染树中渲染对象的信息,计算出每一个渲染对象的位置和尺寸

  • 回流:在布局完成后,发现了某个部分发生了变化影响了布局,那就需要倒回去重新渲染。

  • 根据计算好的信息绘制页面

  • 绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。

  • 重绘:某个元素的背景颜色,文字颜色等,不影响元素周围或内部布局的属性,将只会引起浏览器的重绘。

  • 回流:某个元素的尺寸发生了变化,则需重新计算渲染树,重新渲染。

七、断开连接

当数据传送完毕,需要断开 tcp 连接,此时发起 tcp 四次挥手。

  • 发起方向被动方发送报文,Fin、Ack、Seq,表示已经没有数据传输了。并进入 FIN_WAIT_1 状态。(第一次挥手:由浏览器发起的,发送给服务器,我请求报文发送完了,你准备关闭吧)

  • 被动方发送报文,Ack、Seq,表示同意关闭请求。此时主机发起方进入 FIN_WAIT_2 状态。(第二次挥手:由服务器发起的,告诉浏览器,我请求报文接受完了,我准备关闭了,你也准备吧)

  • 被动方向发起方发送报文段,Fin、Ack、Seq,请求关闭连接。并进入 LAST_ACK 状态。(第三次挥手:由服务器发起,告诉浏览器,我响应报文发送完了,你准备关闭吧)

  • 发起方向被动方发送报文段,Ack、Seq。然后进入等待 TIME_WAIT 状态。被动方收到发起方的报文段以后关闭连接。发起方等待一定时间未收到回复,则正常关闭。(第四次挥手:由浏览器发起,告诉服务器,我响应报文接受完了,我准备关闭了,你也准备吧)

浏览器在解析过程中,如果遇到请求外部资源时,请求过程是异步的,并不会影响HTML文档进行加载,但是当文档加载过程中遇到JS文件,HTML文档会挂起渲染过程,不仅要等到文档中JS文件加载完毕还要等待解析执行完毕,才会继续HTML的渲染过程。原因是因为JS有可能修改DOM结构,这就意味着JS执行完成前,后续所有资源的下载是没有必要的,这就是JS阻塞后续资源下载的根本原因。CSS文件的加载不影响JS文件的加载,但是却影响JS文件的执行。JS代码执行前浏览器必须保证CSS文件已经下载并加载完毕。