五千年(敝帚自珍)

主题:【原创】新时代新潮流WebOS 【1】 -- 邓侃

共:💬594 🌺1902
分页树展主题 · 全看首页 上页
/ 40
下页 末页
      • 家园 乱弹123

        1.HTML + CSS这个“遗产”是很丰富的,从1.0,2.0,3.2,4.01到5.0,特别注意的是5.0目前还是草稿(draft)。为了兼容以前的标准,这个代价实在是高了点。如果5.0草案中的某些东西可以落实的话,不是CSS变成SVG的子集,而是SVG从功能上变成了HTML的“子集”。

        2.当一颗树过度复杂的的时候,为什么不把其中的一部分再次抽象为一个叶子。这样的原始树是不是更加“平衡”?这样的东西是不是更容易实现,你用PLUGIN也好,用未来的NATIVE CLIENT也成,甚至在render engine中再生成一个子树的“实例”。

        3.当用户鼠标在浏览器上滑动的时候,Webkit一个最本能的反应就是 --- 是不是要变换光标?窗口是很笨的,只能被动地变换光标。于是乎layout被触发了;视情况,然后可能触发RenderTree --- 比如链接变色或者PLUGIN消息转发。

        所以说,研究WEBKIT要从浏览器的一端开始。

        • 家园 Layout为什么调用频繁

          当用户鼠标在浏览器上滑动的时候,Webkit一个最本能的反应就是 --- 是不是要变换光标?窗口是很笨的,只能被动地变换光标。于是乎layout被触发了;视情况,然后可能触发RenderTree --- 比如链接变色或者PLUGIN消息转发。

          太守的分析非常有道理。

          关于HTML5,依我看这个东东目前争议还比较大,需要一段时间后,大家才会统一认识。

          当一颗树过度复杂的的时候,为什么不把其中的一部分再次抽象为一个叶子。。。甚至在render engine中再生成一个子树的“实例”。

          听起来,这个主意和frame差不太远。

      • 家园 图3图4看不清

        顶一下,先看"文章",然后再等着看有高清图的"文档"

        算layout的时候同时算paint可以帮助确定每个节点的具体尺寸,但是这个尺寸会不会随窗口大小和分标率变化?发生这些变化的时候layout重算吗?

        • 家园 回调 layout

          每个节点的具体尺寸会不会随窗口大小和分标率变化?发生这些变化的时候layout重算吗?

          是的,每当窗口大小发生变化,layout都得重算。

          高清图的"文档"

          点击“Courtesy”,那里有高清图可以下载。

      • 家园 layout和paint分开

        主要是layout的执行次数少,仅在page load和js修改innerHTML的时候才需要执行,所以虽然计算量大,但是算好以后就可以使用多次。

        paint是on demand的,每次页面显示的时候都需要被调用,所以通常是独立的。另外针对paint有相应的优化。

        你说的第二个问题:layout是否一定要做长方形区域的假设。我想这个问题应该这么问:Layout 过程假设每个RenderTree 的节点都对应一个长方形逻辑区域。这是一个形式和内容的问题。layout解决的,是内容问题。如果仔细看你的第二个图的话,里面的那些字,也是在一个个长方形里面的,不同于图1的,是在显示方式(形式)上的不同。所以,这个问题,似乎应该由paint来处理:

        用layout来确定文档中各个元素的三维位置,然后由paint来解决具体的呈现方式。设想一下用浏览器来看VRML的情形...

        • 家园 英雄所见略同

          Layout 过程假设每个RenderTree 的节点都对应一个长方形逻辑区域。这是一个形式和内容的问题。layout解决的,是内容问题。如果仔细看你的第二个图的话,里面的那些字,也是在一个个长方形里面的,不同于图1的,是在显示方式(形式)上的不同。所以,这个问题,似乎应该由paint来处理:

          用layout来确定文档中各个元素的三维位置,然后由paint来解决具体的呈现方式。设想一下用浏览器来看VRML的情形...

          一语点醒梦中人,Layout不应该受限于2D,而应该从3D考虑。在Paint的时候,无非是把3D实物,投影到2D。

          这样,建3D RenderTree容易,2D Rendering也容易。

          主要是layout的执行次数少,仅在page load和js修改innerHTML的时候才需要执行,所以虽然计算量大,但是算好以后就可以使用多次。

          刚开始我们也是这么认为的,但是实地跟踪一下以后,发现layout经常被调用。具体哪些事件触发了layout,我们也不是非常清楚。或许用户鼠标在浏览器上滑动的时候,Webkit误以为是在改变浏览器视窗大小吧。

      • 家园 小沙发
    • 家园 【原创】【20】WebKit的结构与解构

      【20】WebKit的结构与解构

      从指定一个HTML文本文件,到绘制出一幅布局复杂,字体多样,内含图片音频视频等等多媒体内容的网页,这是一个复杂的过程。在这个过程中Webkit所做的一切,都是围绕DOM Tree和Rendering Tree这两个核心。上一章我们谈到这两棵树各自的功用,这一章,我们借一个简单的HTML文件,展示一下DOM Tree和Rendering Tree的具体构成,同时解剖一下Webkit是如何构造这两棵树的。

      点看全图

      外链图片需谨慎,可能会被源头改

      Figure 1. From HTML to webpage, and the underlying DOM tree and rendering tree.

      Courtesy http://farm4.static.flickr.com/3351/3556972420_23a30366c2_o.jpg

      1. DOM Tree 与 Rendering Tree 的结构

      Figure 1中左上是一个简单的HTML文本文件,右上是Webkit rendering engine绘制出来的页面。页面的内容包括一个标题,“AI”,一行正文,“Ape's Intelligence”,以及一幅照片。整个页面分成前后两个层面,标题和正文绘制在前一个层面,照片处于后一个层面。L君和我亦步亦趋地跟踪了 Webkit,从解析这个HTML文本文件,到生成DOM Tree和Rendering Tree的各个步骤,目的是为了了解DOM Tree和Rendering Tree的具体构成,和构造过程。

      先说Figure 1中左下角的DOM Tree。基本上HTML文本文件中每个tag,在webkit/webcore/html中都有一个class与之对应。譬如<HTML> tag 对应HTMLHtmlElement,<HEAD> tag 对应HTMLHeadElement,<STYLE> tag 对应HTMLStyleElement 等等。比较特别的是DOM Tree的根节点,HTMLDocument,在HTML文本文件中没有哪个tag与之对应。关于HTMLDocument的作用,我们稍后介绍。整个 DOM Tree的结构,与HTML文本文件中各个tags的嵌套关系也一一对应。一言以蔽之,DOM Tree就是把HTML文本文件翻译成object树状结构。

      需要强调的是,DOM Tree是一个通用数据结构,任何XML文本文件都可以翻译成DOM Tree,而不仅仅限于HTML文本文件。webkit/webcore/html 中林林总总html classes,基本上都是webkit/webcore/dom 中的某个class的子类,也就是说,/html 是 /dom的一个特例。这样的设计,为将来把Webkit拓展到HTML格式以外的页面的布局和渲染,埋下了伏笔。所以严格地讲,Figure 1中左下的DOM Tree,实际上是一个HTML DOM Tree。

      再看Rendering Tree,显著的特点在于,

      a. 整个Rendering Tree树状结构,与HTML DOM Tree树状结构一一对应。也就是说,几乎每个HTML DOM Tree中的节点,在Rendering Tree中都有对应的节点。节点与节点之间的父子或兄弟关系也一一对应。

      例外的是,在HTML DOM Tree有HTMLStyleElement叶子节点,而在Rendering Tree中,没有相应的叶子节点。原因是,Rendering Tree各个节点,都涉及页面中某块区域的布局和渲染。而HTMLStyleElement,并不直接涉及某块区域的布局和渲染,HTML DOM Tree中HTMLStyleElement叶子节点包含的内容,已经融入Rendering Tree中RenderImage叶子节点的属性中去了。另外,因为Rendering Tree中不存在与HTMLStyleElement相应的叶子节点,所以,与HTMLHeadElement对应的节点也没有必要存在。

      b. webkit/webcore/rendering中各个class与HTML tags并没有一一对应的关系。

      Rendering Tree是一个通用的规划页面布局和渲染的机制,这个通用机制可以服务于HTML页面,但是并不仅仅限于为HTML页面服务,我们可以用 Rendering Tree来规划其它格式的页面的布局和渲染。以DOM Tree和Rendering Tree为核心的Webkit渲染机,是一个功能强大,扩展性良好的通用渲染机。它不仅可以用来绘制HTML页面,也可以用来渲染其它格式的页面,譬如可以用它来制作email阅读和管理器,制作数据库管理工具,甚至制作游戏界面。

      稍微让人有点吃惊的是,对于 HTMLHtmlElement,HTMLBodyElement,HTMLHeadingElement和HTMLParagraphElement,在Rendering Tree中通通以RenderBlock呼应。如果说HTMLHeadingElement和HTMLParagraphElement的区别不大,仅仅是字体和对齐方式有些微小的差别,所以Rendering Tree可以用RenderBlock来统一应对。那么问题是,HTMLHtmlElement和HTMLBodyElement是两种容器,总是出现在 DOM Tree的中部,而从来不会作为叶子节点出现,对应于这样的容器节点,为什么Rendering Tree不另设一种class,与RenderBlock有所区别呢?不过话又说回来,这不是个大问题,最多是个美感的问题。

      点看全图

      外链图片需谨慎,可能会被源头改

      Figure 2. The construction sequence of the root of the DOM tree.

      Courtesy http://farm4.static.flickr.com/3010/3554310018_e34d271344_o.jpg

      2. DOM Tree 与 Rendering Tree 的根节点

      前一节中我们提到HTMLDocument是一个比较特殊的class,它是整个HTML DOM Tree的根节点,但是不对应任何HTML tag。JavaScript中经常出现的document,指的就是这个根。例如,

      “document.getElementById(x).style.background="yellow";”

      HTML文本文件,通常是以<HTML>开头,以</HTML>结尾。但是<HTML> tag并不对应DOM Tree的根节点,而是根以下的第一个子节点,即HTMLHtmlElement节点。

      初看Figure 2 觉得有点意外,当用户在浏览器里打开一个空白页面的时候,立刻生成了DOM Tree的根节点HTMLDocument,与Rendering Tree的根节点RenderView。而这个时候,用户并没有给定URL,也就是说,对于浏览器来讲,这时候具体的HTML文本文件并不存在。根节点与具体HTML内容相脱节,或许暗示了Webkit的两个设计思路,

      a. DOM Tree的根节点HTMLDocument,与Rendering Tree的根节点RenderView,可以重复利用。

      当用户在同一个浏览器页面中,先后打开两个不同的URLs,也就是两个不同的HTML文本文件时,HTMLDocument和RenderView两个根节点并没有发生改变,改变的是HTMLHtmlElement以下的子树,以及对应的Rendering Tree的子树。

      为什么这样设计?原因是HTMLDocument和RenderView服从于浏览器页面的设置,譬如页面的大小和在整个屏幕中的位置等等。这些设置与页面中要显示什么的内容无关。同时HTMLDocument绑定HTMLTokenizer和HTMLParser,这两个构件也与某一个具体的HTML内容无关。

      b. 同一个DOM Tree的根节点可以悬挂多个HTML子树,同一个Rendering Tree的根节点可以悬挂多个RenderBlock子树。

      在我们目前所见到的浏览器中,每一个页面通常只显示一个HTML文件。虽然一个HTML文件可以分割成多个frames,每个frame承载一个独立的 HTML文件,但是从DOM Tree结构来讲,HTMLDocument根节点以下,只有一个子节点,这个子节点是HTMLHtmlElement,它领衔某个HTML文本文件对应的子树。Rendering Tree也一样,目前我们见到的网页中,一个RenderView根节点以下,也只有一个RenderBlock子节点。

      但是Webkit的设计,却允许同一个根以下,悬挂多个HTML子树。虽然我们目前没有看到一个页面中,并存多个HTML文件,并存多个布局和渲染风格的情景,但是Webkit为将来的拓展留下了空间。前文中所设想的个性化,多皮肤,多视角的浏览器页面绘制,用Webkit实现起来难度不大。

      点看全图

      外链图片需谨慎,可能会被源头改

      Figure 3. The construction sequence of the DOM Tree and the Rendering Tree.

      Courtesy http://farm4.static.flickr.com/3627/3554182242_b0bec88534_b.jpg

      3. DOM Tree 与 Rendering Tree 的构筑

      HTMLDocument 根节点包含的最重要的构件是HTMLTokenizer,而HTMLTokenizer又包含HTMLParser这个构件。HTMLTokenizer 从前到后读取HTML文本文件中每一个字符,并从中提取出各个HTML tags以及它们的内容。而HTMLParser不仅负责HTML DOM Tree的构筑,而且也同时负责Rendering Tree的构筑。

      在Figure 3中,从第8步到第11步,HTMLParser根据一个HTML Tag生成一个HTML DOM Tree节点。从第12步到第17步,生成相应的Rendering Tree的节点,并把它和HTML DOM Tree的节点勾连在一起。这张图的细节过多,读解不容易。Figure 4把第8步到第17步演示了一下。

      点看全图

      外链图片需谨慎,可能会被源头改

      Figure 4. An illustration of the construction of a DOM tree node and its corresponding Rendering tree node.

      Courtesy http://farm4.static.flickr.com/3306/3554259140_3deb9736ea_o.jpg

      值得注意的是,每当HTMLParser生成一个DOM Tree的节点的时候,相应地,也同时生成一个Rendering Tree节点。然后把它们两个新节点勾连在一起。换而言之,Rendering Tree与DOM Tree同步生长。

      Webkit值得赞赏的地方非常多,但是HTMLParser让DOM Tree和Rendering Tree同步生长的做法,却值得商榷。如果同步生长,那么Rendering Tree必然平铺直叙地刻板地忠实于DOM Tree。假设先生成DOM Tree,再生成Rendering Tree,把两者割裂开,就有机会让Webkit发挥更加奇妙的布局和渲染。平铺直叙固然符合大多数人在大多数时间里的阅读习惯,但是离经叛道的设计,也会有市场。一个例子就是上一章末尾处那张多视点的地图。如果让DOM Tree与Rendering Tree同步生长,这样的布局和渲染是难以想像的。

      关键词(Tags): #硅谷评论
      • 家园 【讨论】乱弹123

        1.XML(含HTML)的处理历来就有DOM派和SAX派(不是SEX派),至于详细的看一看这里 --- Choosing between SAX and DOM。虽然给人贴标签有点文()革遗风,让人有点不齿,但俺还是要给楼主拍个队,画个线。俺的看法是LZ是表面上的DOM派,骨子里面的SAX派。没有办法,手机那个平台(AP),内存又小(好像大部分小于等于256MB),还特别怕CPU累着(怕费电),于是楼主就鼠首两端 --- 骑墙派也忒不好玩。

        2.楼主的那个例子就代表个理论问题,不说明真正的实际工程问题 --- 那个DOM tree忒小了,简直是塔克拉马丹大沙漠里的一棵小草。“真正的”DOM TREE可以用FIREFOX中的DOM INSPECTOR看看新浪,网易,乃至于西西河的网页,哪里是棵树,简直就是老百姓家里的柴火堆。 比较柴火堆的DOM TREE和Rendering Tree更有实际意义,比如内存占用量,计算时间等等。这个网页太简单的时候,DOM和SAX没有区别,这有点让俺想起了N年前的网络段子 --- 如果俺有了钱。如果俺有了钱,俺就雇上N多的程序员写个两个Render ENGINE,一个用DOM,一个用SAX,内存多了就用DOM,CPU快了就用SAX。

        3.每个RENDER ENGINE中都有些类似人体上阑尾的退化器官,至于要不要把这些“退化器官”割掉,那就仁者见仁,智者见智了。

        • 家园 太守不是在批评,是替我喊冤

          1. SAX基本不叫座。之所以把HTML文本文件翻译成DOM Tree,图得就是个操作方便。如果把DOM替换成SAX,固然内存中少了DOM Tree这么个庞然大物,但是操作就费事儿了,用一遍一遍SAX扫描HTML文本,可不是闹着玩的。

          2. 内存占用是个大麻烦,Webkit中搞了个RenderArena,自己控制内存的使用。很有点意思,值得仔细琢磨琢磨。

          3. Webkit很有潜力可挖,先别着急割阑尾。稍加改造,jQuery那些东东,根本不在话下。

      • 家园 我也在准备板砖

        恩,不过这板砖也可供您老砸别人,嘿嘿

分页树展主题 · 全看首页 上页
/ 40
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河