浏览器的页面渲染

文本内容主要包括以下几点:
  • Ø  浏览器内核的组成;
  • Ø  浏览器渲染引擎的工作原理
  • Ø  浏览器渲染过程中出现的reflow和repaint

一、浏览器内核组成:渲染引擎和JS引擎,不同的浏览器、即使同一浏览器不同型号可能渲染引擎和JS引擎都不一样。

1.渲染引擎

1)Trident页面渲染引擎 –> IE系列浏览器;

2)Gecko页面渲染引擎 –> Mozilla Firefox;

3)KHTML页面渲染引擎或WebKit框架 –> Safafi和Google Chrome;

4)Presto页面渲染引擎 –> Opera

2.JS引擎

1)JScript引擎 –> IE系列浏览器;

2)spiderMonkey引擎 –> Mozilla Firefox;

3)V8引擎 –> Google Chrome;

4)linear b/futhark引擎 –> Opera

详细信息参考:http://www.mac52ipod.cn/post/Trident-Gecko-WebKit-Presto.php

二、渲染引擎如何工作的?网上这个例子说的很详细:

1.用户输入网址,浏览器向服务器发出请求,服务器返回html文件;

2.浏览器开始载入html代码,发现<head>标签内有一个<link>标签引用外部CSS文件;

3.浏览器又发出CSS文件的请求,服务器返回这个CSS文件;

4.浏览器继续载入html中<body>部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了;

5.浏览器在代码中发现一个<img>标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码;

6.服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码;

7.浏览器发现了一个包含一行Javascript代码的<script>标签,赶快运行它;

8.Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个<div> (style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码;

9.终于等到了</html>的到来;

10.等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径;

11.浏览器召集了在座的各位<div><span><ul><li>们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。

我们看出IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的;在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完);在下载过程中,如果遇到某一标签是嵌入文件,并且文件是具有语义解释性的(例如:JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载,并且在下载后进行解析,解析(JS、CSS中如有重定义,后定义函数将覆盖前定义函数)过程中,停止页面所有往下元素的下载;样式表文件比较特殊,在其下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行样式渲染。并以此方式一直渲染下去,直到整个页面渲染完成。

详细信息参考:http://hi.baidu.com/lhwrwvksqabgjwq/item/6d864c919bd65dbb82d29571

三、关于渲染过程中出现的repaint/reflow

1.什么情况下出现?

当页面首次加载时,需要对文档结构进行解析,同时需要结合各种各样的样式来计算这个页面长什么样子,最后再经过浏览器的渲染页面就出现了。这整个过程细说起来还是比较复杂,其中充满了repaint和reflow。对于DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式(浏览器的、开发人员定义的等)来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow;当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称之为repaint。

其次,在页面加载完成后,用户的一些操作、脚本的一些操作都会导致浏览器发生这种行为。

当出现大量的reflow和repaint的时候,页面不断的重绘导致加载渲染很慢,很影响用户体验,所以需要尽量的减少reflow和repaint。

  1. 2. 如何优化?避免在document上直接进行频繁的DOM操作,如果确实需要可以采用off-document的方式进行,具体的方法包括但不完全包括以下几种:

1) 先将元素从document中删除,完成修改后再把元素放回原来的位置;

2) 将元素的display设置为”none”,完成修改后再把display修改为原来的值;

3) 如果需要创建多个DOM节点,可以使用DocumentFragment创建完后一次性的加入document。

参考:http://km.oa.com/group/1163/articles/show/68284?kmref=search

原文地址:https://www.cnblogs.com/fredshare/p/2790458.html