如果有人问我们,从输入url到渲染页面发生了什么,你可能会想,这不就是读取html,css还有js吗,这么简单有什么好说的,但其实,这其中大有文章。当我们在浏览器中输入一个URL时,背后发生了一系列复杂而协调的过程,将用户的请求转化为一个可视化的网页。
本文将深入解析从输入URL到页面渲染的整个过程,涉及网络请求、HTML解析、CSS样式计算、布局、渲染等多个环节。
一、 URL解析
首先,浏览器解析输入的URL,提取协议、主机名、端口号等信息。随后,通过DNS解析获取服务器的IP地址,建立与服务器的网络连接。
-
URL解析: 用户在浏览器地址栏输入URL时,浏览器首先对URL进行解析。这个过程包括解析协议(如HTTP或HTTPS)、主机名、端口号、路径和查询参数等。解析后,浏览器能够理解用户想要访问的资源的详细信息。
-
DNS解析: 一旦浏览器解析出主机名(域名),它需要将域名转换为服务器的IP地址。这个过程被称为域名系统(DNS)解析。浏览器会向DNS服务器发送请求,获取相应域名对应的IP地址。这是为了建立与服务器的网络连接。
整个过程中,URL解析和网络请求是网页加载过程的第一步,为后续的HTML解析和资源获取打下了基础。这个阶段的效率和速度对于用户体验至关重要。
二、 HTTP请求和服务器响应
一旦网络连接建立,浏览器向服务器发送HTTP请求,请求特定的资源。服务器接收到请求后,返回相应的HTTP响应,其中包括HTML文档及其他可能的资源,如CSS、JavaScript、图像等。这个过程是实现客户端与服务器通信的核心。
HTTP请求和服务器响应是客户端与服务器之间进行通信的关键步骤,是构建现代网页的基础。
HTTP请求过程
-
建立网络连接: 客户端(通常是浏览器)通过DNS解析获取服务器的IP地址,并使用TCP/IP协议与服务器建立网络连接。这通常发生在80端口(HTTP)或443端口(HTTPS)。
-
构建HTTP请求: 客户端构建一个HTTP请求报文,其中包括以下关键信息:
- 请求行: 包含请求方法(GET、POST等)、请求的资源路径(URL中的路径部分)、以及HTTP协议版本。
- 请求头: 包含关于请求的元信息,如用户代理(User-Agent)、接受的数据类型(Accept)、以及可能的其他信息。
- 请求体(对于POST请求等): 包含客户端发送给服务器的数据。
-
发送HTTP请求: 客户端将构建好的HTTP请求通过之前建立的网络连接发送到服务器。
-
等待服务器响应: 客户端等待服务器的响应。这是阻塞的过程,直到服务器返回HTTP响应或超时。
服务器响应过程
-
接收HTTP请求: 服务器接收客户端发送的HTTP请求。
-
解析HTTP请求: 服务器解析HTTP请求报文,提取其中的请求行、请求头和请求体等信息。
-
处理请求: 服务器根据请求的内容和服务器上的逻辑进行处理,可能包括查询数据库、执行应用程序代码等。
-
构建HTTP响应: 服务器构建一个HTTP响应报文,其中包括以下关键信息:
- 状态行: 包含状态码(例如200表示成功,404表示未找到,500表示服务器错误)和HTTP协议版本。
- 响应头: 包含服务器返回的元信息,如内容类型(Content-Type)、内容长度(Content-Length)等。
- 响应体: 包含服务器返回给客户端的实际数据,如HTML文档、图像等。
-
发送HTTP响应: 服务器通过之前建立的网络连接将构建好的HTTP响应发送回客户端。
-
客户端接收响应: 客户端接收服务器的HTTP响应。
-
解析HTTP响应: 客户端解析HTTP响应报文,提取其中的状态行、响应头和响应体等信息。
-
处理响应: 客户端根据响应的内容执行相应的操作,可能包括渲染页面、执行JavaScript代码等。
这样,HTTP请求和服务器响应的完整过程就完成了。整个过程中,通信双方通过发送和接收HTTP报文来实现信息的交换,从而使用户能够在浏览器中访问和与服务器上的资源交互。
三、 HTML解析和DOM构建
浏览器开始解析HTML文档,构建文档对象模型(DOM)表示页面的结构。这一阶段涉及将HTML代码转换为浏览器能够理解的树状结构,为后续的样式计算和布局提供基础。
HTML解析和DOM构建是网页加载过程中的关键步骤,它们负责将从服务器获取的HTML文档转化为浏览器能够理解的文档对象模型(DOM)。以下是HTML解析和DOM构建的完整过程:
-
接收HTML文档: 浏览器通过网络请求获取服务器返回的HTML文档。
-
字节流转换为字符流: HTML文档以字节流的形式传输,浏览器首先将字节流转换为字符流。这通常涉及到字符编码的处理,例如UTF-8。
-
词法分析(Lexical Analysis): 浏览器对字符流进行词法分析,将文档划分为一系列的标记(tokens)。标记是HTML文档中的最小单元,包括标签、属性、文本等。
-
语法分析(Syntax Analysis): 浏览器进行语法分析,根据HTML的语法规则将标记组织成树状结构,即文档对象模型(DOM)树。
-
构建DOM树: 在构建DOM树的过程中,浏览器会识别HTML标签,将它们转化为DOM节点,并确定它们之间的父子关系。这个过程也包括处理文本节点、属性等。
整个HTML解析和DOM构建的过程是一个逐步深入的过程,最终将HTML文档转化为能够在浏览器中渲染的可视化页面。这个过程是浏览器实现网页加载和渲染的基础,对于理解网页性能优化和开发高效的前端应用至关重要。
四、 CSS解析和样式计算
随着HTML的解析,浏览器解析CSS样式表,构建样式规则,并将其应用到DOM元素上,形成渲染树。这一过程决定了页面元素的外观和布局。
CSS解析和样式计算是网页加载过程中的关键步骤,它们负责将从服务器获取的CSS样式表转换为浏览器能够应用到文档的样式规则。以下是CSS解析和样式计算的完整过程:
-
获取CSS文件: 当浏览器解析HTML文档时,如果文档中包含了外部样式表(通过link标签或@import规则引入),浏览器会发起网络请求,获取对应的CSS文件。
-
字节流转换为字符流: 与HTML文档一样,浏览器将CSS文件中的字节流转换为字符流,并进行字符编码处理。
-
词法分析(Lexical Analysis): 浏览器对CSS字符流进行词法分析,将其划分为一系列的令牌(tokens)。这些令牌包括选择器、属性名、属性值等。
-
语法分析(Syntax Analysis): 浏览器进行CSS语法分析,将令牌组织成样式规则的树状结构,即样式表对象模型(CSSOM)。
-
构建样式规则: 在构建CSSOM的过程中,浏览器会识别CSS规则,将其转化为浏览器能够理解的样式规则。这包括选择器和对应的样式声明块,每个声明块包含了一个或多个属性-值对。
-
将样式规则应用到DOM: 样式规则需要应用到文档的DOM树上。浏览器会匹配文档中的DOM节点和样式规则中的选择器,确定哪些样式规则应该应用到哪些DOM节点上。
-
计算样式值: 对于每个匹配的样式规则,浏览器会计算最终的样式值。这可能涉及到继承、层叠(Cascade)和特定性(Specificity)等概念,以确定应该应用哪个样式值。
整个CSS解析和样式计算的过程是浏览器将样式应用到文档的关键阶段,它决定了最终呈现在用户屏幕上的页面样式。理解这一过程对于前端开发者优化网页性能和调试样式问题至关重要。
五、 渲染树构建和布局计算
渲染树是由DOM树和CSS样式规则合并而成的,包含了需要在页面上渲染的所有元素。在这个阶段,浏览器进行布局计算,确定每个元素在页面上的位置和大小。这是网页加载过程中一个关键的步骤,决定了页面的最终呈现效果。
渲染树构建和布局计算是网页加载过程中的重要环节,它们决定了页面最终的呈现效果。以下是渲染树构建和布局计算的完整过程:
-
生成DOM树: 在HTML解析过程中,浏览器将HTML文档解析为文档对象模型(DOM)树,表示文档的结构和内容。
-
生成CSSOM: 在CSS解析过程中,浏览器将样式表解析为样式表对象模型(CSSOM),表示文档的样式信息。
-
生成渲染树: 浏览器将DOM树和CSSOM结合起来,生成渲染树。渲染树是DOM树和CSSOM的结合体,仅包含需要在页面上渲染的元素,以及它们的样式信息。在生成渲染树的过程中,浏览器会忽略不需要渲染的元素,比如
<head>
中的内容。 -
布局计算(Layout): 渲染树构建完成后,浏览器进行布局计算。布局计算确定了每个渲染树节点在屏幕上的位置和大小。这个过程包括计算盒模型、处理浮动、计算文本的大小等。
-
生成位置和尺寸信息: 布局计算完成后,浏览器为每个渲染树节点生成位置和尺寸信息。这些信息是为了后续的绘制阶段做准备,确保每个节点在正确的位置上正确地显示。
整个渲染树构建和布局计算的过程是一个有序的流程,确保了页面元素的正确渲染和布局。这一过程中的性能优化对于提升用户体验和加速页面加载至关重要。理解渲染树构建和布局计算的机制有助于前端开发者更有效地优化页面性能。
六、 绘制和重排重绘
重绘(Repaint)和重排(Reflow)是网页渲染中的两个关键概念,它们指的是浏览器重新绘制页面的过程。
重绘和重排过程
什么是重排 / 回流?
- 浏览器计算页面布局的过程,叫做重排
- 当一个容器的几何属性发生变更时,页面会发生重排
- 改变窗口尺寸
- 改变元素尺寸
- 增加或者删除可见元素
- 页面初次渲染
什么是重绘?
- 将已经计算好布局的容器在屏幕上展示出来
- 元素的非几何属性发生改变,会发生重绘
- 修改背景颜色
- 修改背景颜色
- 修改边框颜色
- 字体颜色
- 重排一定重绘
- 重绘不一定重排
重绘和重排过程:
-
触发事件或样式变化: 重绘和重排通常是由用户交互、JavaScript脚本或样式变化等操作触发的。例如,用户点击按钮、修改DOM元素的样式、改变窗口大小等。
-
生成渲染树: 在触发事件或样式变化后,浏览器需要重新生成渲染树。渲染树是DOM树和CSSOM的结合,包含需要在页面上渲染的元素和其样式信息。
-
重排(Reflow): 重排是指浏览器根据新的渲染树重新计算元素的几何属性,包括位置、大小等。这可能涉及到整个渲染树的重新布局。重排是比较昂贵的操作,因为它会触发整个布局流程。
-
重绘(Repaint): 重排后,浏览器需要重新绘制受影响的元素。重绘是指更新元素的可见样式,而不影响其几何属性。相对于重排,重绘的开销较小。
-
绘制阶段: 重排和重绘都会涉及到绘制阶段,其中浏览器将计算得到的布局信息转换为实际的像素,准备好将来的绘制。
-
渲染到屏幕: 绘制完成后,浏览器将最新的渲染结果显示在屏幕上,更新用户视图。
重绘和重排是高度耦合的过程,它们可能会相互触发。例如,一个元素的样式变化可能导致其周围元素的重新布局,从而触发重排。在实际开发中,减少重排和重绘的次数是性能优化的重要方面。
优化策略
-
使用类名切换样式: 避免直接修改元素的样式,而是通过为元素添加或删除类名来切换样式。这样可以减少重排和重绘的发生次数。
-
使用文档片段(Document Fragment): 在修改DOM时,可以使用文档片段进行离线操作,最后再将文档片段添加到DOM中,减少重排次数。
-
批量操作: 对于多次样式变化或DOM操作,可以通过合并操作,减少对DOM的访问,从而减少重排和重绘的次数。
-
使用
requestAnimationFrame
: 对于需要进行动画的操作,使用requestAnimationFrame
来执行,浏览器会在下一次重绘前执行,避免不必要的重排和重绘。
理解重排和重绘的过程,并采取相应的优化策略,有助于提高页面性能,提升用户体验。
基于布局计算,浏览器开始在屏幕上绘制页面的内容。这可能涉及到绘制整个页面或仅绘制变化的部分。如果页面发生交互或样式改变,浏览器可能需要进行重绘(只重新绘制元素的可见部分)和重排(重新计算元素的布局),以确保页面保持最新状态。
七、 JavaScript执行
如果HTML文档中包含JavaScript代码,浏览器会执行这些脚本。JavaScript可以修改DOM结构、样式或触发异步请求,对页面的行为和外观产生影响。
原文链接:https://juejin.cn/post/7320224895228133388 作者:知了知了__