看过不少文章之后,自己也想尝试写下浏览器到底是如何解析页面的,这对前端工程师来说,应该也算有点帮助。
什么是渲染引擎?
大家都见过webkit吧,有时候我们在写css3时需要兼容不同浏览器,所以就要写不同的前缀,那么这个webkit就是一种渲染引擎,不同的浏览器可能有不同的渲染引擎,下面只列出一些常用的。
Trident:
· Internet Explorer(IE)
· 傲游
Gecko:
· Firefox
· 网景(6至9)
KHTML(webkit):
· Safari
· Google Chrome
Presto:
· Opera
其中,渲染引擎包括了浏览器的核心功能,例如html解释器,css解释器,布局和javascript引擎,例如webkit所用的js引擎就是大名鼎鼎的v8,正是由于浏览器所用的渲染引擎不同,才导致了那么多的浏览器兼容性问题。
浏览器是如何工作的:
上面这个图是我从网上找过之后修改的。
首先流程说一下:
1. 当浏览器通过网络下载到html页面后,开始进行解析,首先要经过html解释器。
2. 在解析html时,发现了css标签和javascript标签,便调用css解释器和javascript引擎,而在解析html的同时,会把html生成dom树。
3. 由于javascript可能对html页面进行修改,所以javascript引擎,html页面,dom树3个是循环过程。
4. css解释器在工作的时候例如webkit css phaser,可以看下图:
可以看到,对css的解析是分两条线,分别解析selectors和declaration最后把得到的结果加在dom树上。
5.DOM之后,需要将其中的元素对象同样式信息结合起来,计算它们的大小位置等布局信息,形成一个能够表示这所有信息的内部表示模型。
6. 把前几布的结果综合起来,就可以进行绘制,从而展现出页面。
7. 最后解释图中虚线箭头的指向含义。它们表示在渲染过程中,每个阶段可能使用到的其他模块。在网页内容的下载中,需要使用到网络和存储,这个是显而易见地。但计算布局和绘图的时候,需要使用2D/3D的图形模块,同时因为要生成最后的可视化结果,这时候需要开始解码音频视频和图片,同其它内容一起绘制到最后的图像中。
其中:
就是渲染引擎 webkit。
由此可见,可以总结出以下问题:
1. 浏览器一般常驻3条线程:js引擎线程,GUI渲染线程,和浏览器事件触发线程。
2. 其中GUI渲染线程和js引擎线程是互斥的,所以说,让浏览器解析js时,是无法继续渲染页面的,所以问题也就是一般吧js放在body底部的原因。
3. 而为什么GUI渲染线程和js引擎线程是互斥的?我想是因为在解析js时,可能会对页面结构进行修改,所以渲染线程需要挂起,来等待js解析完毕才能执行页面渲染。
4. css是并行加载的,但是并行也有加载限制,例如浏览器在对同一域名下下载css有个数限制,所以就会有一些静态文件需要放在不同的的域名下来加载,提高速度。可看下图:
5. 在css里如果写import来引入,会打断css的并行下载,这样不利于页面渲染,和css的解析。
6. reflow和repaint分别对应上个流程图的html解释和绘制阶段,所以:
- 当 DOM 元素的属性发生变化 (如 color) 时,而这些属性只是影响元素的外观风格,浏览器会通知 render 重描相应的元素,此过程称为 Repaint。
- 如果该次变化涉及元素布局 (如 width),浏览器则抛弃原有属性,重新计算并把结果传递给 render 以重新描绘页面元素, 此过程称为 Reflow。
- Reflow必将引起Repaint,而Repaint不一定会引起Reflow 。
总结:
同过了解浏览器的工作原理来对页面进行性能优化是必须的。
参考:http://blog.csdn.net/milado_nju/article/details/11661311