浏览器-03 WebKit 渲染1
WebKit
是一个渲染引擎,而不是一个浏览器;DOM
是对HTML
或者XML
等文档的一种结构化表示方法,通过这种方式,用户可以通过提供标准的接口来访问页面中的任何元素的相关属性,并可对DOM
进行相应的添加、删除和更新操作等;- 基于
DOM
树的一些可视的节点,WebKit
来根据需要来创建相应的RenderObject
节点,这些节点也构成了Render
树; - 基于
Render
树,WebKit
也会根据需要来为它们中的某些节点创建新的RenderLayer
节点, 从而形成RenderLayer
树; WebKit
的布局计算和浏览器的渲染,GPU
硬件加速都依赖Render
树和RenderLayer
树;
Render树
Render
树的建立
-
Render
树节点和DOM
树节点不是一一对应关系;下面情况下需要建立新的Render
节点:
*DOM
树的document
节点;
*DOM
树中的可视化节点,如HTML,BODY,DIV
等;
* 某些情况下需要建立匿名的Render
节点,该节点不对应于DOM
树中的任何节点; -
Render
树建立后,布局运算会计算出相关的属性;其中有位置,大小,是否浮动等;渲染引擎利用这些信息绘制这些元素;
RenderObject
类及其子类
RenderObject
是Render
树的节点基础类,提供了一组公共的接口;它在DOM
树创建或DOM
中有动态加入元素时创建;- 它有很多的子类,这些子类可能对应一些
DOM 树
中的节点,如RenderText
,有些则是容器类,如RenderBlock
;
匿名RenderBlock
对象
CSS
中有块级元素和内嵌元素之分;RenderBlock
用来表示块级元素,;- 为了处理上的方便,某些情况下需要建立匿名的
RenderBlock
对象;因为RenderBlock
的子女必须都是内嵌的元素或都是非内嵌的元素;所以,当它包两种元素的时,它会为相邻的内嵌元素创建一个块级RenderBlock
节点, 然后设置该节点为自己的子女并且设置这些内嵌元素为它的子女;
RenderLayer树
RenderLayer
树的建立
-
RenderLayer
节点和Render
节点不是一一对应关系;以下情况下RenderObject
节点需要建立新的RenderLayer
节点:
*DOM
树的document
节点对应的RenderView
节点;
*DOM
树中的document
的子女节点,也就是HTML
节点对应的RenderBlock
节点;
* 显式的CSS
位置;
* 有透明效果的对象;
* 节点有溢出(overflow),alpha
或者反射等效果;
*Canvas 2D
和3D (WebGL)
*Video
节点对应的RenderObject
对象; -
一个
RenderLayer
被建立后,其所在的RenderObject
对象的所有后代均包在该RenderLayer
,除非这些后代需要建立自己的RenderLayer
; -
后代的
RenderLayer
的父亲就是自己最近的祖先所在的不同的RenderLayer
,这样,它们也构成了一颗RenderLayer
树;
形成可视化内容
-
每个
RenderLayer
对应的Render
节点内容均会绘制在该RenderLayer
所对应的层次上(或者内部存储结构上); -
不同的
RenderLayer
可以共享同一个内部存储结构,也可以有各自的后端存储,这取决于不同的移植; -
在软件渲染下, 通常各个
RenderLayer
的内容都绘制在同一块后端存储上;在GPU硬件加速的下,某些RenderLayer
可能有自己独立的后端存储; -
之后通过合成器来把这些不同的后端合成在一起,最终形成网页的可视化内容;
-
RenderLayer
在创建RenderObject
对象的时候,如果需要,也会同时被创建;也有可能在执行JavaScript
代码时,更新页面的样式从而需要新创建一个RenderLayer
;
一个渲染例子
-
源码:
-
这段
HTML
源代码被WebKit
解析后会生成一颗DOM
树;当DOM
树生成时,WebKit
同时建立了一颗Render
树;
-
上图中的
layer at (x, x)
表示不同的RenderLayer
节点,下面的所有RenderObject
均属于该RenderLayer
; -
最大的部分-第二个
layer
,包了HTML
中的绝大部分元素;
*Head
元素没有相应的RenderObject
;
*Canvas
元素不在其中,而是在第三个layer
中(RenderHTMLCanvas
);但是它仍然是RenderBody
节点的子节点;
* 匿名的RenderBlock
节点, 包含了RenderText, RenderInline
等节点; -
第三个
layer
:因为从Canvas
创建了一个WebGL3D Context
对象,这里需要重新生成一个新的layer
; -
三个
layer
的创建时间:第一和第二个layer
在创建DOM
树后,会触发创建;第三个layer
测试资源加载解析好之后,执行后面的JavaScript
代码后所创建;