现代浏览器引擎复杂,它们执行多个任务来实现网页的加载、渲染和交互等功能
域名解析(DNS解析)
当您在浏览器中输入URL(统一资源定位符)时,浏览器首先会提取其中的域名部分(例如,www.baidu.com)。浏览器会向本地操作系统或者递归的DNS解析器发出域名解析请求。
解析器会按照DNS层次结构向根域名服务器逐级查询,最终找到负责该域名的 authoritative DNS 服务器。这个服务器会返回与该域名对应的IP地址。
- 本地操作系统会首先查看本地的DNS缓存,如果有对应域名的IP地址记录,就会返回该IP地址。
- 如果本地缓存没有记录,操作系统会向预配置的DNS解析器(通常由Internet服务提供商ISP提供)发送解析请求。
URL(统一资源定位符)由多个组成部分构成,包括:
-
协议(Protocol): 表示要使用的协议或协议类型,例如HTTP、HTTPS、FTP等。
-
域名(Domain): 标识要访问的网站的名称,例如www.example.com。
-
端口(Port): 指定服务器上正在监听的端口号。大多数协议都有默认的端口号,如HTTP为80,HTTPS为443。在URL中,如果使用默认端口,通常会被省略。
-
路径(Path): 标识服务器上的特定资源的路径,例如/index.html。
-
查询参数(Query Parameters): 包含在URL中以“?”符号开始的键值对,用于向服务器传递附加信息,例如/search?q=keyword。
-
片段标识(Fragment Identifier): 以“#”符号开始,用于标识文档中的特定位置,通常用于在页面内部进行导航。
建立TCP连接
通过解析得到的IP地址,浏览器将发起与目标服务器的TCP连接。这是通过TCP三次握手(SYN、SYN-ACK、ACK)来建立可靠的连接。
发起HTTP请求
一旦TCP连接建立,浏览器会向服务器发送一个HTTP请求。这个请求中包含了您输入URL中的路径、参数、请求方法(GET、POST等)以及其他必要的头部信息。
响应完成之后怎么办?TCP 连接就断开了吗?
在HTTP/1.0中,默认情况下,每个HTTP请求/响应周期都会创建一个新的TCP连接,这意味着在响应完成后,TCP连接会关闭。然而,为了减少TCP连接的频繁建立和关闭所带来的开销,以及提高性能,HTTP/1.1引入了持久连接(也称为“长连接”)。
在持久连接中,TCP连接在一个HTTP请求/响应周期完成后不会立即关闭,而是保持打开状态,以便在同一连接上发送更多的请求和响应。这可以显著减少TCP连接的建立和关闭次数,从而提高性能。
持久连接的实现依赖于以下机制:
-
Connection: keep-alive 头部: 在HTTP/1.1中,可以使用
Connection: keep-alive
头部来指示服务器和客户端保持持久连接。 -
Pipeline(流水线): 在持久连接中,客户端可以在一个连接上发送多个请求,而无需等待每个响应。这种机制称为流水线,它允许在一个连接上并行发送多个请求,而不必等待前一个请求的响应。
-
Connection Timeout(连接超时): 尽管连接是持久的,但在一定时间内如果没有新的请求/响应交换,连接可能会由于超时而关闭。
-
并发连接限制: 服务器和浏览器都可能对持久连接的数量进行限制,以确保不会过多地消耗资源。
所以响应完成之后TCP 连接不一定断开。TCP连接是否断开取决于使用的HTTP版本、服务器和客户端的配置、持久连接的机制
请求响应处理
服务器处理请求
服务器接收到请求后,根据请求的内容和路径执行相应的操作。这可能涉及到查询数据库、处理业务逻辑等。
服务器返回HTTP响应
服务器处理完请求后,会生成一个HTTP响应。这个响应包含了状态码、响应头部(包含例如内容类型、内容长度等信息)以及实际的内容(HTML、图片、CSS、JavaScript等)。
浏览器接收响应
浏览器接收到服务器返回的HTTP响应后,会根据响应头部中的内容类型来确定如何处理响应体的数据。浏览器接收到响应成功的报文后便开始下载网页。
浏览器解析渲染页面
浏览器在接收到HTML,CSS,JS文件之后,它是如何将页面渲染在屏幕上的?
呈现页面
如果响应的内容是HTML页面,浏览器会开始解析HTML,构建DOM(文档对象模型)树,同时也会请求页面中引用的其他资源,如CSS样式表、JavaScript文件、图片等。
解析和渲染
浏览器解析DOM树和CSS样式,然后将它们组合在一起以创建渲染树。渲染树包含了页面上所有可见的元素及其样式信息。
解析HTML构建DOM Tree
首先会根据顶部定义的DTD
类型进行对应的解析,解析过程将被交给内部的GUI渲染线程来处理。
DTD(Document Type Definition)
将HTML网页或资源从字节流解释成DOM树
结构:
词法分析(Lexical Analysis): 解析器会将HTML代码分解为一系列称为“词法单元”或“标记”的部分,包括元素、属性、文本内容等。词法分析器将HTML代码解析成一个个标记,同时识别标记的类型和内容。
语法分析(Syntax Analysis): 解析器根据词法分析阶段产生的标记,使用HTML的语法规则构建一个语法树,也称为解析树(Parse Tree)。这个树结构表示了HTML文档的嵌套关系和结构。
构建DOM树:
多线程执行: 现代浏览器在渲染网页时使用多个线程来处理不同的任务,以提高性能和响应能力。主要涉及以下几个线程:
-
GUI渲染线程: 负责将DOM树和CSSOM树的布局和样式信息渲染到屏幕上,实现图像的绘制和显示。
-
JavaScript引擎线程: 负责解析和执行JavaScript代码。这个线程执行JS代码并可能修改DOM树,但在执行期间会阻塞GUI渲染线程。
-
网络线程: 负责处理网络请求,例如加载HTML、CSS、JavaScript、图片等资源。
-
定时触发线程: 负责执行计时器任务,例如
setTimeout
、setInterval
等。
解析HTML和构建DOM树: HTML解析器将HTML代码解析为标记,然后将这些标记构建成解析树。在线程化的解释器中,可以将解析HTML的过程交给单独的线程来处理,以提高效率。这个线程将HTML代码拆分为标记,并将解析树的部分内容发送回渲染线程。然后,在渲染线程中,DOM树的构建发生,浏览器解析HTML标记并根据标记构建DOM树,表示网页结构。
JavaScript执行和DOM修改: 当JavaScript引擎线程执行JavaScript代码时,它可能会修改DOM树,例如插入、删除、修改元素等。由于JavaScript执行和DOM修改可能会影响网页的布局和显示,浏览器在执行JavaScript时会暂停GUI渲染线程,以确保DOM的一致性。
资源加载: 资源加载涉及到网络线程,它负责从服务器下载HTML、CSS、JavaScript、图像等资源。这些资源可能是异步加载的,也就是说,加载它们的过程不会阻塞DOM树的构建。如果在DOM树构建过程中遇到需要等待的资源,例如图片加载,GUI渲染线程会继续处理其他内容,待资源加载完成后,会触发相应的回调来更新DOM。
解析CSS构建CSSOM Tree
CSS解释器会将CSS文件解释成内部表示结构,生成CSS规则树,这个过程也是和DOM解析类似的,CSS
字节转换成字符,接着词法解析与法解析,最后构成 CSS对象模型(CSSOM)
的树结构
布局和绘制
浏览器使用渲染树来进行布局(确定每个元素在屏幕上的位置和大小)和绘制(将元素渲染到屏幕上)。这涉及到计算元素的确切位置、大小以及层叠顺序等。
这个过程比较复杂,涉及到两个概念: reflow(回流)和repain(重绘)
交互和动态更新
页面的JavaScript代码可以使页面在不刷新的情况下进行动态更新,例如通过AJAX请求获取数据并更新页面内容。
加载完毕
页面所有资源加载完成,浏览器完成渲染和执行后,页面就完全加载并可以与用户进行交互了。