http://blog.csdn.net/luoshengyang/article/details/50558942
「在Chromium中,Render进程是通过Browser进程下载网页内容的,后者又是通过共享内存将下载回来的网页内容交给前者的。Render进程获得网页内容之后,会交给WebKit进行处理。WebKit所做的第一个处理就是对网页内容进行解析,解析的结果是得到一棵DOM Tree。DOM Tree是网页的一种结构化描述,也是网页渲染的基础。本文接下来就对网页DOM Tree的创建过程进行详细分析。」
「网页的DOM Tree的根节点是一个Document。Document是依附在一个DOM Window之上。DOM Window又是和一个Frame关联在一起的。Document、DOM Window和Frame都是WebKit里面的概念,其中Frame又是和Chromium的Content模块中的Render Frame相对应的。Render Frame是和网页的Frame Tree相关的一个概念。关于网页的Frame Tree,可以参考前面Chromium Frame Tree创建过程分析一文。」
上面描述的各种对象的关系可以通过图1描述,如下所示:
图1 Frame、DOM Window和Document的关系
「从前面Chromium Frame Tree创建过程分析一文可以知道,有的Render Frame只是一个Proxy,称为Render Frame Proxy。Render Frame Proxy描述的是在另外一个Render进程中进行加载和渲染的网页。这种网页在WebKit里面对应的Frame和DOM Window分别称为Remote Frame和Remote DOM Window。由于Render Frame Proxy描述的网页不是在当前Render进程中加载和渲染,因此它是没有Document的。
相应地,Render Frame描述的是在当前Render进程中进行加载和渲染的网页,它是具有Document的,并且这种网页在WebKit里面对应的Frame和DOM Window分别称为Local Frame和Local DOM Window。
从图1我们还可以看到,在Render Frame和Local Frame之间,以及Render Frame Proxy和Remote Frame之间,分别存在一个Web Local Frame和Web Remote Frame。Web Local Frame和Web Remote Frame是属于WebKit Glue层的概念。从前面Chromium网页加载过程简要介绍和学习计划一文可以知道,WebKit Glue层的作用是将WebKit的对象类型转化为Chromium的对象类型,这样Chromium的Content层就可以用统一的、自有的方式管理所有的对象。关于Chromium的层次划分和每一个层次的作用,可以参考前面Chromium网页加载过程简要介绍和学习计划一文。
除了根节点,也就是Document节点,DOM Tree的每一个子结点对应的都是网页里面的一个HTML标签。并不是所有的HTML标签都是需要渲染的,例如script标签就不需要进行渲染。对于需要渲染的HTML标签,它们会关联有一个Render Object。这些Render Object会形成一个Render Object Tree,如图2所示:
图2 DOM Tree与Render Object Tree、Render Layer Tree和Graphics Layer Tree的关系
为了便于执行绘制操作,具有相同坐标空间的Render Object会绘制在同一个Render Layer中。这些Render Layer又会形成一个Render Layer Tree。绘制操作是由图形渲染引擎执行的。对于图形渲染引擎来说,Layer是一个具有后端存储的概念。在软件渲染模式中,Layer的后端存储实际上就是一个内存缓冲区。在硬件渲染模式中,Layerr的后端存储实际上就是一个FBO。为了节约资源,WebKit不会为每一个Render Layer都分配一个后端存储,而是会让某些Render Layer共用其它的Render Layer的后端存储。那些具有自己的后端存储的Render Layer,又称为Graphics Layer。这些Graphics Layer又形成了一个Graphics Layer Tree。
Render Object Tree、Render Layer Tree和Graphics Layer Tree都是和网页渲染相关概念,它们是从DOM Tree发展而来的。因此,在分析网页的渲染机制之前,有必要了解网页的DOM Tree的创建过程。
DOM Tree的创建发生在WebKit解析网页内容的过程中。WebKit在解析网页内容的时候,会用到一个栈。每当碰到一个HTML标签的起始Token,就会将其压入栈中,而当碰到该HTML标签的结束Token时,就会将其弹出栈。在这些HTML标签的压栈和出栈过程中,就可以得到一棵DOM Tree。以图2所示的DOM Tree片段为例,它对应的网页内容为:
<div>
<p>
<div></div>
</p>
<span></span>
</div>
各个标签的压栈和出栈过程如图3所示:
图3 网页内容解析过程中的HTML标签压栈和出栈操作
接下来,我们就结合源码分析WebKit在解析网页内容的过程中创建DOM Tree的过程。从前面Chromium网页URL加载过程分析一文可以知道,Browser进程一边下载网页的内容,一边将下载回来的网页交给Render进程的Content模块。Render进程的Content模块经过简单的处理之后,又会交给WebKit进行解析。WebKit是从ResourceLoader类的成员函数didReceiveData开始接收Chromium的Content模块传递过来的网页内容的,因此我们就从这个函数开始分析WebKit解析网页内容的过程,也就是网页DOM Tree的创建过程。
网友评论