本文参考以色列开发人员塔利·加希尔的研究成果。这是原文。
我只是提炼一下文章中对我有用的知识点。
浏览器的构成
1. 用户界面 - 包括地址栏、后退/前进按钮、书签目录等,也就是你所看到的除了用来显示你所请求页面的主窗口之外的其他部分。
2. 浏览器引擎 - 用来查询及操作渲染引擎的接口。
3. 渲染引擎 - 用来显示请求的内容,例如,如果请求内容为html,它负责解析html及css,并将解析后的结果显示出来。
4. 网络 - 用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作。
5. UI后端 - 用来绘制类似组合选择框及对话框等基本组件,具有不特定于某个平台的通用接口,底层使用操作系统的用户接口。
6. JS解释器 - 用来解释执行JS代码。
7. 数据存储 - 属于持久层,浏览器需要在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术
这篇博客主要是第三部分,渲染引擎。
浏览器在解析html文档时,是从上到下解析,把html中的标签全部转换为dom树中的节点。通过解析html创建出了dom树。
dom树的根是document对象。dom树的节点与html文档中的标签是一一对应关系。如下代码:
<html>
<body>
<p>
Hello DOM
</p>
<div><img src=”example.png” /></div>
</body>
</html>
会被转化为下面的dom树
dom树的构建原理
解析html采用的是符号识别算法,简单说来,就是把html中的每个标签都识别为一个符号,规范中给每个符号定义了相对应的dom元素,所以这些符号被树构造器处理成,对应的dom元素。最后这些元素会被添加到dom树上。
对css文件解析会生成css规则,css规则与dom树结合之后生成渲染树。构建好渲染树之后是布局渲染树。最后是绘制渲染树。
这一系列过程是解析完一部分内容,就在浏览器上将其渲染出来。也就是说,浏览器并不会等html都解析完了后再去构建和布局render树。渲染引擎将会尽可能早的将内容呈现到屏幕上。
渲染树的定义
渲染树中的每个渲染对象用一个和该节点的css盒模型对应的矩形区域来表示(被称为帧或盒),包含宽高位置之类的几何信息。但是渲染对象和dom元素并不是一一对应的,比如display属性为none的dom元素,不会出现在渲染树中。
当DOM的变化影响了元素的几何属性(宽或高),比如以下这些情况:
1.添加或者删除可见的DOM元素
2.元素位置改变
3.元素尺寸改变
4.元素内容改变(例如:一个文本被另一个不同尺寸的图片替代)
5.页面渲染初始化(这个无法避免)
6.浏览器窗口尺寸改变
浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。这个过程称为重排。
完成重排后,浏览器会重新绘制受影响的部分到屏幕,该过程称为重绘。
注意还有一些时候会触发重排重绘,就是获取布局信息的时候
比如:
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop, scrollLeft, scrollWidth, scrollHeight
- clientTop, clientLeft, clientWidth, clientHeight
- getComputedStyle() (currentStyle in IE)
以上属性和方法需要返回最新的布局信息,因此浏览器不得不执行渲染队列中的“待处理变化”并触发重排以返回正确的值。