话说这个前端面试经常问的题目,但仔细查阅了一下资料,发现想要很深入地理解,还是非常困难的,所以自己打算简单梳理一遍,不讨论过多细节,以便加深记忆。
主要流程:
1. 输入URL
首先输入URL,浏览器可能会做一些预处理,一般会根据之前的统计记录来预判输入字符可能对应的URL,比如输入bai
,浏览器根据之前的浏览记录发现可能会访问www.baidu.com
,从而开始建立TCP (Transmission Control Protocol)链接甚至开始渲染,输入URL后,浏览器会对URL进行检查,首先判断协议,还会判断URL的安全性,接着就准备DNS解析了。
2. DNS解析
首先了解2个概念:
- IP地址:IP 协议为互联网上的每一个网络和每一台主机分配的一个逻辑地址。IP 地址如同门牌号码,通过 IP 地址才能确定一台主机位置。服务器本质也是一台主机,想要访问某个服务器,必须先知道它的 IP 地址,IP 地址由四个数字组成,中间用点号连接。
- 补充说明:光靠IP地址也是无法通信的,因为IP地址并非和某台设备绑定,比如你的电脑在家IP地址为192.168.1.1,但是到办公室就变成172.22.22.22 了,这就需要我们的MAC(media access control) 地址,这是固定并且唯一的。
- DNS:Domain Name System的缩写,即域名系统。它是internet提供一项服务,也叫域名解析服务,主要作用是将域名解析成对应的IP地址,域名系统分为正向解析和反向解析,正向解析就是讲域名解析成IP地址,反向是讲IP地址解析成域名,一般用于后端。
域名与IP地址之间是呈一一对应的关系,但多个域名可以对应同一个IP地址。由于IP地址全是数字,为了简单好记,采用域名来代替IP地址表示站点地址。
在Internet上,一个域名要由两台域名服务器提供“权威性的”域名解析,这两台域名服务器,和您的域名一起被登记在域名注册管理机构的数据库中,如果是国际域名,域名注册管理机构就是Internic;如果是国内域名,域名注册管理机构就是CNNIC(China Internet Network Information Center),这两台“权威性的”服务器,一主一辅,保存着相同的记录,主要是为了提高可靠性。域名注册管理机构的数据库的记录最终体现在“根”域名服务器上。
DNS解析过程:
- 浏览器搜索自己DNS缓存
- 从系统hosts文件中查找DNS缓存
- 搜索路由器的DNS缓存
- 搜索ISP中的DNS缓存
- 如果还未找到对应IP地址,则向根服务器查找域名对应IP, 根域名服务器把请求发到下一级,直到找到IP
- 将得到的IP返回给操作系统,同时自己也将IP地址缓存起来(这个缓存的记录有一个失效期,当失效期到了后,您的主控DNS服务器将会自动丢弃缓存的记录)
- 操作系统将IP返回给浏览器,同时浏览器也将IP地址缓存起来
3. 通过 Socket 发送数据
- 调用 Socket API 后内核会对数据进行底层协议栈的封装,接下来启动 DMA(direct memory access)控制器,它将从内存中读取数据写入网卡。
- 连接 Wi-Fi 路由,Wi-Fi 网卡需要通过 Wi-Fi 路由来与外部通信,原理是基于无线电,通过电流变化来产生无线电,这个过程也叫「调制」,而反过来无线电可以引起电磁场变化,从而产生电流变化,利用这个原理就能将无线电中的信息解读出来就叫「解调」。因为内网设备的 IP 都是类似 192.168.1.x这样的内网地址,外网无法直接向这个地址发送数据,所以网络数据在经过路由时,路由会修改相关地址和端口,这个操作称为 NAT(Network Address Translation)映射。家庭路由一般会通过双绞线连接到运营商网络的。
- 数据过双绞线发送到运营商网络后,还会经过很多个中间路由转发,当数据传递到这些路由器后,路由器会取出包中目的地址的前缀,通过内部的转发表查找对应的输出链路
- 数据最终通过光纤进入服务器机房,最后通过交换机的端口将数据发往机架中的服务器
4. 建立连接--三次握手
- 主机向服务器发送一个建立连接的请求(您好,我想认识您)
- 服务器接到请求后发送同意连接的信号(好的,很高兴认识您)
- 主机接到同意连接的信号后,再次向服务器发送了确认信号(我也很高兴认识您),自此,主机与服务器两者建立了连接
5.网页请求
当服务器与主机建立了连接之后,下面主机便与服务器进行通信。网页请求是一个单向请求的过程,即是一个主机向服务器请求数据,服务器返回相应的数据的过程
- 浏览器根据 URL 内容生成 HTTP 请求,请求中包含请求文件的位置、请求文件的方式等等
- 服务器接到请求后,会根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件
- 服务器将得到的 HTML 文件发送给浏览器
- 在浏览器还没有完全接收 HTML 文件时便开始渲染、显示网页
- 在执行 HTML 中代码时,根据需要,浏览器会继续请求图片、CSS、JavsScript等文件,过程同请求 HTML
6. 网页渲染
主流程示例
简单点说就是:
- 呈现引擎将开始解析 HTML 文档,并将各标记逐个转化成“内容树”上的 DOM节点。同时也会解析外部 CSS 文件以及样式元素中的样式数据。HTML 中这些带有视觉指令的样式信息将用于创建另一个树结构:呈现树。
- 呈现树包含多个带有视觉属性(如颜色和尺寸)的矩形。这些矩形的排列顺序就是它们将在屏幕上显示的顺序。
- 呈现树构建完毕之后,进入“布局”处理阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标。下一个阶段是绘制- 呈现引擎会遍历呈现树,由用户界面后端层将每个节点绘制出来。
1. 解析
html解析生成DOM树
浏览器中的呈现引擎(render engine)解析html文档,呈现引擎解析的语法是过程可以分为2部分:词法分析和语法分析。词法分析器(有时也称为标记生成器),负责将输入内容分解成一个个有效标记;而解析器负责根据语言的语法规则分析文档的结构,从而构建解析树。
因为常规解析器用的是与上下文无关的语法,而html语言比较“宽容”,对常见的无效html用法采取包容态度等原因,所以它的语法不是与上下文无关的语法,不能用常规解析器来解析(但css和JavaScript 可以),所以需要一些工具自动生成解析器,您只要向其提供您所用语言的语法(词汇和语法规则),它就会生成相应的解析器。WebKit 使用了两种非常有名的解析器生成器:用于创建词法分析器的 Flex 以及用于创建解析器的 Bison(您也可能遇到 Lex 和 Yacc 这样的别名)。Flex 的输入是包含标记的正则表达式定义的文件。Bison 的输入是采用 BNF 格式的语言语法规则。HTML 解析器的任务是将 HTML 标记解析成解析树。
解析器的输出“解析树”是由 DOM 元素和属性节点构成的树结构。DOM 与标记之间几乎是一一对应的关系。比如下面这段标记:
<html>
<body>
<p>
Hello World
</p>
<div> ![](example.png)</div>
</body>
</html>
可以翻译成下面的DOM树
CSS解析生成CSS规则树
浏览器解析器都会将 CSS 文件解析成 StyleSheet 对象,且每个对象都包含 CSS 规则。CSS 规则对象则包含选择器和声明对象,以及其他与 CSS 语法对应的对象。
脚本解析
网络的模型是同步的。网页作者希望解析器遇到 <script> 标记时立即解析并执行脚本。文档的解析将停止,直到脚本执行完毕。如果脚本是外部的,那么解析过程会停止,直到从网络同步抓取资源完成后再继续。此模型已经使用了多年,也在 HTML4 和 HTML5 规范中进行了指定。作者也可以将脚本标注为“defer”,这样它就不会停止文档解析,而是等到解析结束才执行。HTML5 增加了一个选项,可将脚本标记为异步,以便由其他线程解析和执行。
2. 呈现树构建
在 DOM 树构建的同时,浏览器还会构建另一个树结构:呈现树。这是由可视化元素按照其显示顺序而组成的树,也是文档的可视化表示。呈现器是和 DOM 元素相对应的,但并非一一对应。非可视化的 DOM 元素不会插入呈现树中,例如“head”元素。如果元素的 display 属性值为“none”,那么也不会显示在呈现树中(但是 visibility 属性值为“hidden”的元素仍会显示)。
在 WebKit 中,解析样式和创建呈现器的过程称为“附加”。每个 DOM 节点都有一个“attach”方法。附加是同步进行的,将节点插入 DOM 树需要调用新的节点“attach”方法。
3. 布局
HTML 采用基于流的布局模型,这意味着大多数情况下只要一次遍历就能计算出几何信息。处于流中靠后位置元素通常不会影响靠前位置元素的几何特征,因此布局可以按从左至右、从上至下的顺序遍历文档。但是也有例外情况,比如 HTML 表格的计算就需要不止一次的遍历。布局是一个递归的过程。它从根呈现器(对应于 HTML 文档的 <html> 元素)开始,然后递归遍历部分或所有的框架层次结构,为每一个需要计算的呈现器计算几何信息。
4.绘制
在绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。绘制工作是使用用户界面基础组件完成的。