共计 1876 个字符,预计需要花费 5 分钟才能阅读完成。
浏览器的渲染过程
首先,咱们先来理解一下浏览器的渲染过程是什么样的,也就是说浏览器把一堆代码出现到页面上的过程是什么样子的,依据下图,咱们能够总结出浏览器的渲染步骤为:
步骤:
1. 解析 HTML 代码,生成 DOM 树(DOM Tree);解析 CSS 代码,生成 CSSOM 树(CSS Tree);
2. 将 DOM 树和 CSSOM 树进行联合从而构建起渲染树(Render Tree);
Render Tree 相似于 DOM Tree,但存在很大的区别:Render Tree 可能辨认款式,Render Tree 中的每个节点都有本人的款式,而且 Render Tree 不蕴含暗藏的节点,比方 display:none 的节点,因为这些节点不会用于页面出现。
3. 回流(Layout),依据生成的 Render Tree,进行 Layout,失去节点的地位、大小;
4. 重绘(Painting),依据 Render Tree 以及回流失去的地位信息,确定各节点的相对地位,失去各节点的相对像素;
5. 出现(Display),将像素发送给 GPU,展现到页面上。
————分割线 ————
在步骤 2 中,渲染树 (Render Tree) 是如果构建的呢?
如上图所示,总结出的构建步骤为:
1. 从 DOM 树的根节点开始遍历每个可见节点;
遍历的是每个可见节点,那么不可见的节点包含:
(a)一些不会渲染输入的节点,比方 script、meta、link 等;
(b)一些通过 css 进行暗藏的节点。比方 display:none。留神,利用 visibility 和 opacity 暗藏的节点,还是会显示在渲染树上的。只有 display:none 的节点才不会显示在渲染树上。
2. 对于每个可见的节点,找到 CSSOM 树中对应的规定,并利用它们;
3. 依据每个可见节点以及其对应的款式,组合生成渲染树。
又是怎么组合的呢?
简略是就是一个匹配的过程,要将每个 HTML 元素节点与之正确的款式相匹配。因为节点地位属性将通过 CSS 选择器链的优先级来决定,渲染树中的某个结点可能会同时满足多个选择器链,这时候就要通过选择器的优先级来实现属性的赋值。
这时候,将渲染结点同时满足的几个选择器链通过其优先级加权算值,从小到大顺次笼罩渲染结点;而如何确定此渲染结点是否满足某个选择器链呢?这也是一个逐层判断的过程:从此渲染结点开始,判断此结点是否与选择器链表的以后选择器相匹配。如果匹配,判断此选择器与下一个选择器的关系:如果为 NONE,示意本选择器是选择器链的最初一个,返回胜利;如果关系为 AND (比方:#id.class),抉择下一个选择器与本渲染结点持续比拟;如果关系为 CHILD,示意本选择器是下一个选择器的子结点,返回下一个选择器与下一个渲染结点的匹配后果;否则,关系为 DESCENDANT,选择器和渲染结点各指向下一个结点,而后将渲染结点持续回溯,直到第一个满足回溯后的选择器的结点,此时将持续判断回溯后的选择器和回溯后的渲染结点是否匹配。
————分割线————
重绘
什么是重绘呢?当 Render Tree 中的一些元素须要更新属性,而这些属性只是影响元素的外观、格调,而 不会影响布局 的,比方扭转背景色彩等,这就会引起浏览器 重绘 (Painting)。
例如:
某网站首页页面中,将蓝色框内导航栏的背景色彩变为粉色,其余的不变,并没有扭转整体布局和各个局部的地位,所以此时会引起重绘,不会引起回流。
回流
当 Render Tree 中的局部节点因为元素的尺寸、布局、暗藏等扭转而须要从新构建,这就会引起浏览器 回流 (reflow)。每个页面至多须要一次回流,就是在页面第一次加载的时候(浏览器渲染过程步骤 3),因为要第一次构建 Render Tree。在回流的时候,浏览器会使渲染树中受到影响的局部生效,并从新结构这部分渲染树,实现回流后,浏览器会从新绘制受影响的局部到屏幕中,即重绘。
例如:
某网站首页页面中,将蓝色框内导航栏间接删掉,则上面的所有局部会进行上移,整体的布局产生了变动,所以此时会引起回流,接着进行重绘。
【在这里引出了回流与重绘的一个最大的区别:
回流肯定会引起重绘,重绘不肯定会引起回流 】
何时会触发回流重绘呢?
(a)增加或删除可见的 DOM 元素;
(b)元素的地位发生变化;
(c)元素的尺寸发生变化(包含外边距、内边框、边框大小、高度和宽度等);
(d)内容发生变化,比方文本变动或图片被另一个不同尺寸的图片所代替;
(e)页面一开始渲染的时候(这必定防止不了);
(f)浏览器的窗口尺寸变动(因为回流是依据视口的大小来计算元素的地位和大小的)……
【作者程度无限,欢送大家在评论区交换斧正~】