前言
输入URL时页面是如何渲染的这是一道范围很大的面试题,这道题包括了页面渲染和网络通信,这篇文章主要讲的是页面渲染
渲染过程
让我们先来看一个渲染过程图
1.输入URL(这里涉及到网络层的知识,我们先忽略)
2.浏览器从服务器获取HTML文件并解析html
我们一步步进行讲解
1.浏览器刚开始并不能完全读懂html文件,需要进行解析,浏览器刚开始拿到的是原始字节数据(16进制),这时候是字节流。
2.然后根据编码(比如UTF-8)将字节转换成各种字符,比如:
<body>Hello, <span>world!</span></body>
这时候就是字符流 3.词法解析
把字符流初步解析成我们可理解的 词,学名叫 token。
什么是词呢?词 是编译原理中的最小单元,如标签开始、属性、标签结束、注释、CDATA节点,Token 会标识出当前 Token 的种类。HTML代码 就像一句话,词法解析 相当于拆解句子,Token类型 就像给每个词标注词性。
<div //检测到开始标签的开头 <div
class="title"// 解析到属性 class,值为 "title"
> //开始标签的结束符 >
Hello //标签内的文本内容
</div> //结束标签 </div>
Tokens 这个阶段中会标识出当前 Token 是 开始标签 或是 结束标签 亦或是 文本 等信息,经历 词法解析 我们把字符流解析成了 词 (Token)。
接着在每个 Token 被生成后,会立刻消耗这个 Token 创建出节点对象,就是 节点 (Nodes) 阶段
把开始结束标签配对、属性赋值好、父子关系这些都连接好了,最终就构成了 DOM 树
后面这两小步也可称为 语法解析 ,到此 DOM Tree 就解析完了
另外多嘴一句,DOM树(DOM Tree) | 文档对象模型 ,这些东西说的都是 DOM树
四、下载和解析 CSS 文件
在构建 DOM 树的过程中,如果 HTML 中包含 <link> 标签引入的 CSS 文件,浏览器会同时发起对这些 CSS 文件的请求。CSS 文件的下载和解析过程与 HTML 类似,但也有一些不同之处。
1. 下载字节码
浏览器接收到服务器返回的 CSS 文件的二进制字节数据。
2. 编码
同样使用 UTF - 8 等编码格式将字节数据解码为 CSS 文本。
3. 词法分析
浏览器对 CSS 文本进行词法分析,将其拆分成一个个的 token(标记),例如选择器、属性名、属性值等。
4. 生成 CSS rule 节点
根据 token 生成 CSS rule 节点,每个节点代表一条 CSS 规则。
5. 构建 CSSOM 树
将 CSS rule 节点组织成一个树形结构,即 CSSOM(CSS Object Model)树。CSSOM 树描述了页面中所有元素的样式信息。
五、构建 RenderTree
DOM 树和 CSSOM 树构建完成后,浏览器会将它们合并成一个新的树——RenderTree。RenderTree 只包含需要显示的元素及其样式信息,那些设置了 display: none 的元素不会出现在 RenderTree 中。
构建 RenderTree 的过程就是将 DOM 元素和对应的 CSS 样式结合起来,确定每个元素的最终样式。例如,如果一个 <p> 元素在 CSS 中被设置了 color: red,那么在 RenderTree 中该元素的颜色属性就会被标记为红色。
六、生成 Layout 树
RenderTree 构建完成后,浏览器还不知道每个元素在页面中的具体位置和大小。因此,需要进行布局计算,生成 Layout 树。
布局计算的过程就是根据盒模型(Box Model)的规则,确定每个元素的尺寸、位置和边距等信息。盒模型是 CSS 中用于描述元素布局的基本模型,它包括内容区域、内边距、边框和外边距。
例如,对于一个设置了 width: 200px、height: 100px、padding: 10px 和 border: 1px solid black 的元素,其在页面中实际占据的宽度为 200 + 10 * 2 + 1 * 2 = 222px,高度为 100 + 10 * 2 + 1 * 2 = 122px。
七、创建图层
在生成 Layout 树之后,浏览器会根据元素的属性(如 z - index、position 等)将页面划分为多个图层。图层的作用是为了提高渲染性能,不同的图层可以独立进行渲染和合成。
1. 层叠上下文
z - index 属性用于控制元素在 z 轴上的堆叠顺序,具有不同 z - index 值的元素会被分配到不同的图层中。例如,一个 z - index 值较大的元素会覆盖在 z - index 值较小的元素之上。
2. 特殊定位元素
position 属性为 fixed 或 sticky 的元素通常会被单独分配到一个图层,这样可以在页面滚动时独立更新这些元素的位置。
3. 动画和变换元素
使用 transition、transform 或 opacity 属性的元素也会被分配到单独的图层,这些属性可以利用 GPU 加速,提高动画的流畅度。例如,translate(50%, 50%, 50%) 可以让元素在 3D 空间中进行平移,并且使用 GPU 进行加速渲染。
八、图层的合并
各个图层独立渲染完成后,浏览器需要将它们合并成一个最终的图像。图层合并的过程就是将各个图层按照它们的堆叠顺序依次绘制到一个平面上,形成最终的像素图像。
九、浏览器的渲染引擎绘制平面
最后,浏览器的渲染引擎将合并后的图像绘制到屏幕上,将像素点呈现给用户。这个过程涉及到硬件加速和图形处理单元(GPU)的使用,以确保页面能够快速、流畅地显示。
十、总结
浏览器页面渲染是一个复杂而又精妙的过程,从输入 URL 到最终的像素呈现,涉及到多个阶段和大量的计算。了解这个过程不仅可以帮助我们更好地理解网页的工作原理,还可以在开发过程中优化页面性能,提高用户体验。
例如,减少不必要的回流和重绘、合理使用 CSS 图层、优化资源加载等,都可以有效地提升页面的加载速度和响应性能。希望通过本文的介绍,你对浏览器页面渲染流程有了更深入的认识。在后续的开发中,我们可以根据这些知识,写出更加高效、流畅的网页。