render树构建(转发)

120 阅读5分钟

render树由dom树与css树构成,dom树主要是为了描述内容,而css树则是描述对文档的样式规则;

构建流程:

浏览器将 DOM 和 CSSOM 合并成一个 渲染树,它会网罗网页上所有可见的 DOM 内容,以及每个节点的所有 CSSOM 样式信息。

image.png

  1. 从 DOM 树的根节点开始遍历每个可见节点

    • 某些节点不可见(例如脚本标记、元标记等),因为它们不会体现在渲染输出中,所以会被忽略。
    • 某些节点通过 CSS 隐藏,因此在渲染树中也会被忽略,例如,样式设置为 display: none 属性的节点。
  2. 对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。

  3. 发射可见节点,连同其内容和计算的样式。

首先了解下什么是DOM树

浏览器将HTML解析成树形的数据结构,简称DOM;

DOM是文档对象模式(Document Object Model)的缩写;是HTML文档的对象标识;解析树的根节点是Document对象;

节点:Node--构成HTML文档最基本的单元;

常用节点分为四类;

1、文档节点:整个HTML文档;

2、元素节点:HTML文档中的HTML标签;

3、属性节点:元素的属性;

4、文本节点:HTML标签中的文本内容;

5、注释节点

childNodes包含了哪些节点?

由childNodes属性返回的数组中包含着所有类型的节点,所有的属性节点和文本节点也包含在其中。

事实上,文档里几乎每一样东西都是一个节点,甚至连空格和换行符都会被解释成节点。而且都包含在childNodes属性所返回的数组中。

chidNoeds返回的事node的集合,

每个node都包含有nodeType属性。

nodeType取值:

元素节点:1

属性节点:2

文本节点:3

注释节点:8

let nodeRoot = document; //根节点
let nodeHTML = nodeRoot[1];  // html节点
let nodeHead = nodeHTML.childNodes[0] // head节点
let nodeBody = nodeHTML.childNodes[1] // body节点
let nodeDiv = nodeBody.childNodes[0] //DIV节点
let nodeText = nodeDiv.childNodes[0] // 文本节点
strText = nodeText.data  //文本节点有data这个属性

可以看下DOM树的基本结构:

image.png

说明:

1.跨域除外,跨域通常是在操作frame 上,简单的说,就是两个frame 不属于同一域名

2.上面的操作为了演示,采用的方法是从根结点一直到文本结点的遍历,在DOM 方法上,有更简洁的方法,这些以后会有更多示例加以说明。

3.DOM树揭示了DOM对象之间的层次关系,这样就方便动态地对html文档进行增删改查。

4.增删改查必须要遵循层次关系

5.文本对象是最底层的节点

6.获取 对象的值 .data

CSS树

主要是对每个节点进行样式描述!

image.png

渲染对象是和 DOM 元素相对应,但这种对应关系并非一一对应,因为有这么些特殊元素:

非可视化元素:非可视化的 DOM 元素不会被插入渲染树中;

<head> 标签以及里面的内容,以及 display:none 的元素也会被去除,但是 visibility: hidden ,opacity: 0的元素仍会显示;

复杂结构元素: 例如, select 元素有 3 个渲染器:一个用于显示区域,一个用于下拉列表框,还有一个用于按钮。如果由于宽度不够,文本无法在一行中显示而分为多行,那么新的行也会作为新的呈现器而添加。

另一个关于多渲染器的例子是格式无效的 HTML。根据 CSS 规范,行内元素只能仅包含块状元素或行内元素中的一种。如果出现了混合内容,则应创建匿名的块状渲染对象,以包裹行内元素。所以我们平时的 inline-block 可以设置宽高。

脱离文档流

部分渲染对象对应于 DOM 节点,但树中所在的位置与 DOM 节点不同。例如,浮动定位和绝对定位的元素处于正常的文本流之外,在两棵树上的位置不同,渲染树上标识出真实的结构,并用一个占位结构标识出它们原来的位置。

image.png

样式计算

构建渲染树之前,需要计算每一个渲染对象的可视化属性。这是通过计算每个元素的样式属性来完成的。

样式包括来自各种来源的样式表行内样式元素和 HTML 中的可视化属性。其中后者经过转化以匹配 CSS 样式属性。

样式表的来源包括浏览器的默认样式表由网页作者提供的样式表以及由浏览器用户提供的用户样式表(浏览器允许您定义自己喜欢的样式。以 Firefox 为例,用户可以将自己喜欢的样式表放在 Firefox Profile 文件夹下)。

样式计算存在以下难点:

  1. 样式数据是一个超大的结构,存储了无数的样式属性,这可能造成内存问题。
  2. 如果不进行优化,为每一个元素查找匹配的规则会造成性能问题。要为每一个元素遍历整个规则列表来寻找匹配规则,这是一项浩大的工程。选择器会具有很复杂的结构,这就会导致某个匹配过程一开始看起来很可能是正确的,但最终发现其实是徒劳的,必须尝试其他匹配路径。
  3. 应用规则涉及到相当复杂的层叠规则(用于定义这些规则的层次)

了解了以上知识点后,再总结一下大概的构建流程:

DOM 树和 CSSOM 树将合并后在浏览器屏幕上渲染像素

  • DOM 树与 CSSOM 树合并后形成渲染树
  • 渲染树只包含渲染网页所需的节点
  • 布局计算每个对象的精确位置和大小
  • 最后一步是绘制,使用最终渲染树将像素渲染到屏幕上

原文地址:tsejx.github.io/javascript-…