浏览器的渲染原理

从上面这个图中,我们可以看到那么几个事:

1)浏览器会解析三个东西:

一个是HTML/SVG/XHTML,事实上,Webkit有三个C++的类对应这三类文档。解析这三种文件会产生一个DOM Tree。
CSS,解析CSS会产生CSS规则树。
Javascript,脚本,主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rule Tree.
2)解析完成后,浏览器引擎会通过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。注意:

Rendering Tree 渲染树并不等同于DOM树,因为一些像Header或display:none的东西就没必要放在渲染树中了。
CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每个Element。也就是DOM结点。也就是所谓的Frame。
然后,计算每个Frame(也就是每个Element)的位置,这又叫layout和reflow过程。
3)最后通过调用操作系统Native GUI的API绘制。

DOM解析

HTML的DOM Tree解析如下:

<body>
<head>
    <title>Web page parsing</title>
</head>
<body>
    <div>
        <h1 >Web page parsing</h1>
        <p>This is an example Web page.</p>
    </div>
</body>
</html>```
上面这段HTML会解析成这样:

![](http://upload-images.jianshu.io/upload_images/4146857-c299c13a0e06f8eb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

```<doc>
<title>A few quotes</title>
<para>
  Franklin said that <quote>"A penny saved is a penny earned."</quote>
</para>
<para>
  FDR said <quote>"We have nothing to fear but <span>fear itself.</span>"</quote>
</para>
</doc>```
于是DOM Tree是这个样子:

![](http://upload-images.jianshu.io/upload_images/4146857-f4ae62813f216bb8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
然后我们的CSS文档是这样的:
`````` /* rule 1 */ doc { display: block; text-indent: 1em; }
/* rule 2 */ title { display: block; font-size: 3em; }
/* rule 3 */ para { display: block; }
/* rule 4 */ [class="emph"] { font-style: italic; }

于是我们的CSS Rule Tree会是这个样子:


注意,图中的第4条规则出现了两次,一次是独立的,一次是在规则3的子结点。所以,我们可以知道,建立CSS Rule Tree是需要比照着DOM Tree来的。CSS匹配DOM Tree主要是从右到左解析CSS的Selector,好多人以为这个事会比较快,其实并不一定。关键还看我们的CSS的Selector怎么写了。

注意:CSS匹配HTML元素是一个相当复杂和有性能问题的事情。所以,你就会在N多地方看到很多人都告诉你,DOM树要小,CSS尽量用id和class,千万不要过渡层叠下去,……

通过这两个树,我们可以得到一个叫Style Context Tree,也就是下面这样(把CSS Rule结点Attach到DOM Tree上):

渲染

渲染的流程基本上如下(黄色的四个步骤):

计算CSS样式
构建Render Tree
Layout – 定位坐标和大小,是否换行,各种position, overflow, z-index属性 ……
正式开画


注意:上图流程中有很多连接线,这表示了Javascript动态修改了DOM属性或是CSS属会导致重新Layout,有些改变不会,就是那些指到天上的箭头,比如,修改后的CSS rule没有被匹配到,等。

这里重要要说两个概念,一个是Reflow,另一个是Repaint。这两个不是一回事。

Repaint——屏幕的一部分要重画,比如某个CSS的背景色变了。但是元素的几何尺寸没有变。
Reflow——意味着元件的几何尺寸变了,我们需要重新验证并计算Render Tree。是Render Tree的一部分或全部发生了变化。这就是Reflow,或是Layout。(HTML使用的是flow based layout,也就是流式布局,所以,如果某元件的几何尺寸发生了变化,需要重新布局,也就叫reflow)reflow 会从<html>这个root frame开始递归往下,依次计算所有的结点几何尺寸和位置,在reflow过程中,可能会增加一些frame,比如一个文本字符串必需被包装起来。

几个工具

Chrome下,Google的SpeedTracer是个非常强悍的工作让你看看你的浏览渲染的成本有多大。其实Safari和Chrome都可以使用开发者工具里的一个Timeline的东东。

Firefox下这个基于Firebug的叫Firebug Paint Events的插件也不错。

IE下你可以用一个叫dynaTrace的IE扩展。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 看到这个标题大家一定会想到这篇神文《How Browsers Work》,这篇文章把浏览器的很多细节讲得很细,而且...
    光小月阅读 747评论 0 4
  • 1)浏览器会解析三个东西:一个是HTML/SVG/XHTML,事实上,Webkit有三个C++的类对应这三类文档。...
    24_Magic阅读 297评论 0 2
  • 首先,看一张图片: 首先是解析:1)这是一个解析的过程,浏览器会解析三个东西:一个是HTML/SVG/XHTML,...
    osborne阅读 370评论 0 0
  • 我们默默地做着浪漫的事 彼此默默地知根知底
    郭绿狮阅读 137评论 0 2