龙珠

修炼自己与发现世界

浏览器是如何工作的?——How Browsers Work:Behind the Scenes of Modern Web Browsers

浏览器是如何工作的?——How Browsers Work:Behind the Scenes of Modern Web Browsers

——Arthur     2011.11.12


实验室例会讲Paper,上周让我做的Presentation,题目就是这篇文章:How Browsers Work:Behind the Scenes of Modern Web Browsers   (http://www.html5rocks.com/en/tutorials/internals/howbrowserswork/

网页看起来不算很多,但打印下来足有40+页。纯英文,开头部分看着还行,逻辑还比较清晰,但越看到后面越觉得混乱。强迫自己做了一下Paper的框架,将主干结构列出,同时加入讲时需要添加的小例子。不充满血肉,只列出骨架。做完这件事之后,顿觉清爽无比。整篇文章就可以像鱼提起来,抖一下,骨骼就显露出来。对帮助理解文章非常有效果。


本想做成思维导图的,但虽说列框架,自己在本子上也写了大概六大页,图不好做,做了贴出来也看不清,所以还是只把框架贴上来。竖向分类时的表现力有些不足,但结构还算很清晰


有人翻译了原文,本次框架里的中文很多是从翻译中copy过来的,有些拿不准的部分再去翻原文看。译文地址:http://blog.csdn.net/zzzaquarius/article/details/6532299

HTML5 Rocks

How Browsers Work:Behind the Scenes of Modern Web Browsers

CH 1 简介

     涉及浏览器:Firefox Chrome Safari(partly open source)

     主要功能:展现网页资源 HTML CSS标准  (W3C维护)

     UI:地址栏、前进后退、书签、刷新、停止、主页

     High Level Structure

CH2 渲染引擎 Rendering Engine

     Gecko:Firefox

     Webkit:Chrome Safari

     Main Flow:先构建DOM Tree→在构建渲染Tree→再据此布局(layout)→绘制(paint)(注:DOM--document object model 文档对象模型)

     Webkit、Gecko的rendering main flow图示见figure 3、4

CH3 解析 Parsing

     3.1 Parsing-general

     解析文件就是把它翻译成为可理解的代码结构。例:2+3-1

     解析分两个子进程:1.lexical analysis 词汇分析:breaking input into tokens       2.syntax analysis 语法分析

     Document→Lexical Analysis→Syntax Analysis→Parse Tree

     解析过程是迭代循环的。

     翻译/转换:经常在解析完毕后,需要翻译成机器代码文件

     Source Code→Parsing→Parse Tree→Translation→Machine Code

     解析示例:2+3-1

     Parser类型:1.top down parsers 从语法的高层结构开始     2.bottom up parsers 从语法的底层结构开始

     3.2 Html Parser(HTML解析)

     不是context free grammar(与上下文无关的语法) 更宽容(forgiving),允许犯错(注:这是HTML流行起来的原因,也是后面提到Error Toleracne(出错忍耐)的原因)

     HTML定义:DTD(Document Type Definition)格式。定义元素、属性、层级

     DOM:文档对象模型注:重点部分

          解析树(parse tree)是由DOM元素及属性节点组成。DOM是html文档的对象表示,作为html元素的外部接口供javascript等调用。

          DOM和标签基本是一一对应关系。示例图figure 8

     解析算法:

          HTML不能用一般的top down或bottom up parsers解析(原因3点)

          因此使用定制的custom parser进行解析。

          其解析规则在HTML5中规定,包含两个部分:符号化(tokenization--即为lexical analysis)、构建树(tree construction)

     

     The tokenization algorithm:略(3.2.6)

     The Tree construction algorithm:略(3.2.7)

     出错忍耐(Error Tolerance):

          浏览器fix网页中的“无效语法”等错误。(因为HTML语言很forgiving——前有提到)

          HTML5中规定了需要注意的错误情形,4种。举例:webkit

3.3 CSS解析

     CSS:Casading Style Sheets 层叠样式表

     context free grammar  与上下文无关的语法,是一种将表示样式应用到标记的系统

     定义了lexical grammar(defined by regular expressions--正则表达式)和syntax grammar(Described in BNF--Backus-Naur Form 巴科斯-诺克范式)

     举例:webkit CSS解析图 figure 12

3.4 处理脚本(Script)和样式表(Style Sheets)的顺序

     Web的模式是同步的。

     Webkit和Firefox做了优化,进行预解析脚本。

CH4 构造渲染树 Render Tree Construction

     DOM树构建完成后,浏览器开始构建渲染树(Render tree)

     渲染树按照显示顺序包含视觉元素,是文档的视觉表示。

     构建渲染树的目的是以正确的顺序绘制(Painting)内容。

     Firefox中叫渲染树中元素为“Frame”(帧)。

     Webkit中叫渲染树中元素为“Render”或“Render Object”。(一个Render知道怎样布局(layout)和绘制(paint)它自己和其子节点)

     Render Tree和DOM Tree的关系:注:重点部分

          对应,但非一一对应。

          不可见的DOM元素不会被插入渲染树。

          一些DOM元素对应几个可见对象。如select元素对应显示区域、下拉列表和按钮三个对象。

          一些渲染对象和所对应的DOM接电不在树上相同的位置。

          图示对应关系:

     构建树的流程:

          Firefox:registered as a listener for DOM updates

          Webkit:teh process fo resolving the style and creating a render is called "attachment"

     样式计算 Style Computation

          构建渲染树需计算每一个渲染对象的视觉属性。

          计算样式的困难,3点:

               1.样式数据过大

               2.寻找元素对应规则易引起性能问题(若不优化的话)

               3.应用规则设计复杂的级联

          浏览器怎么处理这些问题:(注:以下这几个部分很长)

               共享样式数据--4.3.1

               Firefox规则树--4.3.2

               结构化

               使用规则树计算样式上下文

               对规则进行处理以简化匹配流程--4.3.3

               以正确的级联顺序应用规则--4.3.4

               样式表的级联顺序

               Spectify

               对规则排序

     逐步处理:Webkit

CH5 布局 Layout

     计算渲染器的位置、大小等信息,称为Layout(布局--Webkit)或Reflow(回流--Gecko)。

     布局一般按照从左到右、从上到下的顺序。有例外:html tables

     布局是迭代过程,从根渲染器(Root Render)开始。根渲染器位置为(0,0),大小为浏览器窗口的可见部分。

     Dirty Bit系统

          避免为每个小变化而全部重新布局

          将变动的renderer和其children标记为dirty:需要重新布局

          有两个标识:1.dirty     2.Children are dirty:render本身可能OK,但至少有一个孩子(children)需要重新布局

     全局和增量布局

          全局:1.全局样式变动,如字号改变。     2.窗口resize。

          增量:仅dirty renderer重新布局。是异步触发。

     异步和同步布局

          同步:1.全局layout一般均为同步触发。     2.脚本请求信息时,如“offsetHeight”

          异步:增量layout

     优化    

          当layout因resize或者渲染位置改变(而非大小改变)触发时,渲染对象大小会从缓存中读取,而不会重新计算。

          若子树改变,则layout并不从根开始。如:将文本插入文本域。

     Layout过程

          Layout一般有以下四个部分。(略)

     宽度计算

          渲染对象的宽度使用容器的宽度、渲染对象样式中的宽度、margin和borders等进行计算。

          举例:Webkit中:<div class= "Width:30%" />     

          1.容器宽度是容器的可用宽度和0中的最大值,即:

               contentWidth = clientWidth() - paddingLeft() - paddingRight()

               其中,clientWidth表示对象内部大小,不含border和scrollbar。

          2.元素的宽度是指样式属性Width的值(本例中Width为30%);

          3.加上水平方向上的borders和paddings(填充区域)。

          经此3步之后,得到的是“prefered width”,还要与maximum width和minimum width比较,以保证最终宽度结果在二者之间。

     折行 Line Breaking 

     折行时layout创建额外的渲染对象并调用他们的layout。

CH6 绘制 Painting

     和布局一样,绘制也分为全局和增量:

          全局:略

          增量:部分渲染对象改变,但不影响整个树,仅使其在屏幕上对应的矩形区域无效。

                    使OS将其视作“dirty region”,并产生新的“paint event”。

                    Chrome中,由于renderer并非在主线程中,由Chrome模仿OS产生“paint event”

     绘制顺序

          和元素在栈中的存储顺序相同

          背景颜色→背景图片→border→children→outline

     重绘时的优化

          Firefox显示列表:

               Firefox读取渲染树并为绘制矩形创建了一个显示列表,该表以正确绘制顺序包含着矩形相关的渲染对象。这样,重绘时可只需查找一次树,不需多次查找。

               Firefox优化:不添加会被隐藏的元素。如元素完全在其他不透明元素下。

          Webkit矩形存储:

               重绘前,webkit讲旧的矩形保存为位图(bitmap),然后只画新旧矩形的差集。

CH7 动态变化 Dynamic Changes

     浏览器总是试着以最小的动作响应一个变化。

          一个元素颜色变化     →     该元素重绘;

          一个元素位置变化     →     该元素、子元素和相关元素重绘;

          添加DOM数               →     该节点和相关节点重绘;

          主要变化(字号改变等)     →     整体的布局和重绘

CH8 渲染引擎的线程 The Rendering Engine's Threads

     渲染引擎是单线程的。

          Firefox Safari:浏览器主线程

          Chrome:tab主线程

     事件循环:

          浏览器主线程是一个事件循环。它被设计为无限循环以保持执行过程的可用,等待时间(如Layout或Paint事件)并执行它们。 例:Firefox主要事件循环代码:     while(!mExiting)NS_ProcessNextEvent(thread);


CH9 CSS2可视模型

     画布(Canvas):

     CSS2规定Canvas用来描述格式化的结构所渲染的空间——浏览器绘制内容的地方。

     CSS盒模型:

          包括:内容区域(必有。如图片、文本等)及可选的四周的padding、border和margin区域。如图:

     Box布局的方式由:box类型、大小、定位策略和扩展信息(如图片大小或屏幕尺寸)决定。

     定位策略,三种:

          normal:与DOM树,渲染树中的位置一致;

          float:先正常布局,再尽可能向左或右移动;

          absolute:与DOM树中位置无关。

     Box类型:

          1.Block Box

          2.Inline Box

     定位(Positioning)

          1.Relative

          2.Floats

          3.Absolute或Fixed

     层级显示 Layered Representation

          由CSS属性当中的z-index指定,即在z轴上的位置。z值越大,越靠前显示。