# 浏览器渲染机制

# 一、浏览器基础结构

浏览器基础结构主要包括如下7部分:

1.用户界面(User Interface):用户所看到及与之交互的功能组件,如地址栏,返回,前进按钮等;

2.浏览器引擎(Browser engine):负责控制和管理下一级的渲染引擎;

3.渲染引擎(Rendering engine):负责解析用户请求的内容(如HTML或XML,渲染引擎会解析HTML或XML,以及相关CSS,然后返回解析后的内容);

4.网络(Networking):负责处理网络相关的事务,如HTTP请求等;

5.UI后端(UI backend):负责绘制提示框等浏览器组件,其底层使用的是操作系统的用户接口;

6.JavaScript解释器(JavaScript interpreter):负责解析和执行JavaScript代码;

7.数据存储(Data storage):负责持久存储诸如cookie和缓存等应用数据

# 浏览器内核

Trident内核: IE

Webkit内核:Chrome,Safari

Gecko内核:FireFox

# 二、渲染机制(关键渲染路径)

1.构建DOM树(DOM tree):从上到下解析HTML文档生成DOM节点树(DOM tree),也叫内容树(content tree);

2.构建CSSOM(CSS Object Model)树:加载解析样式生成CSSOM树;

3.执行JavaScript:加载并执行JavaScript代码(包括内联代码或外联JavaScript文件);

4.构建渲染树(render tree):根据DOM树和CSSOM树,生成渲染树(render tree);

渲染树:按顺序展示在屏幕上的一系列矩形,这些矩形带有字体,颜色和尺寸等视觉属性。

5.布局(layout):根据渲染树将节点树的每一个节点布局在屏幕上的正确位置;

6.绘制(painting):遍历渲染树绘制所有节点,为每一个节点适用对应的样式,这一过程是通过UI后端模块完成;

image

# 三种tree

image

# 什么情况阻塞渲染

首先渲染的前提是生成渲染树,所以 HTML 和 CSS 肯定会阻塞渲染。如果你想渲染的越快,你越应该降低一开始需要渲染的文件大小,并且扁平层级,优化选择器。

然后当浏览器在解析到 script 标签时,会暂停构建 DOM,完成后才会从暂停的地方重新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的原因。

当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。

当 script 标签加上 defer 属性以后,表示该 JS 文件会并行下载,但是会放到 HTML 解析完成后顺序执行,所以对于这种情况你可以把 script 标签放在任意位置。

对于没有任何依赖的 JS 文件可以加上 async 属性,表示 JS 文件下载和解析不会阻塞渲染。

# HTML文件转换为 DOM 树

当我们打开一个网页时,浏览器都会去请求对应的 HTML 文件。虽然平时我们写代码时都会分为 JS、CSS、HTML 文件,也就是字符串,但是计算机硬件是不理解这些字符串的,所以在网络中传输的内容其实都是 0 和 1 这些字节数据。当浏览器接收到这些字节数据以后,它会将这些字节数据转换为字符串,也就是我们写的代码。

image

当数据转换为字符串以后,浏览器会先将这些字符串通过词法分析转换为标记(token),这一过程在词法分析中叫做标记化(tokenization)。

image

那么什么是标记呢?这其实属于编译原理这一块的内容了。简单来说,标记还是字符串,是构成代码的最小单位。这一过程会将代码分拆成一块块,并给这些内容打上标记,便于理解这些最小单位的代码是什么意思。

image

当结束标记化后,这些标记会紧接着转换为 Node,最后这些 Node 会根据不同 Node 之前的联系构建为一颗 DOM 树。

image

以上就是浏览器从网络中接收到 HTML 文件然后一系列的转换过程。

image

# CSS 文件转换为 CSSOM 树

其实转换 CSS 到 CSSOM 树的过程和上一小节的过程是极其类似的

image

在这一过程中,浏览器会确定下每一个节点的样式到底是什么,并且这一过程其实是很消耗资源的。因为样式你可以自行设置给某个节点,也可以通过继承获得。在这一过程中,浏览器得递归 CSSOM 树,然后确定具体的元素到底是什么样式。

Last Updated: 3/26/2020, 4:20:55 PM