浏览器加载和渲染分析
最近一直在做前端JS开发,为了更清楚的显示页面元素的加载顺序,动手写了一个程序,程序对页面中的每个元素都延迟5秒。
在IE6下查看loader.jsp这个页面,使用HttpWatch来检测页面元素的加载。从下面的图中可以看到加载顺序。
IE6首先加载了页面loader.jsp,
下载了主页面后,页面首先显示的是“红色测试文字”、“蓝色测试文字”几个字,但此时显示的是只是黑色字体,没有样式,因为样式还没有下载下来。
接下来页面中的标签是JS标签,属于嵌入文件,因此IE需要将其下载下来。这有两个文件,虽然IE6同时能够和同一个域 名的WEB Server并发建立两个链接,但是此时并没有使用两个连接,而是使用一个连接,在下载完成后,接下来才下载另外一个文件。
因为IE6浏览器没有对JS的加载做优化,JS文件加载顺序决定解释执行顺序,JS包含了语法定义,在第二个文件里面的函数可能用到了第一个文件里面的变量和函数,IE6没有做判断,如果先下载的是第二个文件,此时就会发生解释错误。JS按先后顺序放好,IE依次下载进行解释。后面的函数覆盖前面的函数定义。
注意:IE6在同步加载执行(当然可以setTimeout异步执行,如:l3.js)JS的时候,不会去下载新的资源,就算JS已经下载完成,只是在本地解释执行,看图片蓝色箭头指向的时间间隔,就是本地JS执行的用去的时间。
在下载完成后,我们看到load1.js,load2.js,l3.js开始顺序执行。而此时字体的样式表和图片仍然没有下载下来。“红色测试文字”,“蓝色测试文字”字体还是黑色显示的。
IE6下面的CSS是并行加载的,在两个CSS文件加载完成后,可以看到 “红色测试文字”,显示为红色, “蓝色测试文字”显示为蓝色,l1.css和 l2.css完成后,l3.css样式还没有下载下来,此时IE使用已经下载到样式对上面的元素渲染了一遍,此时虽然“红色测试文字”,“蓝色测试文字”字体样式显示一样,只是颜色不同相同。第三个文件下载后,此时IE又重新对“红色测试文字”和“蓝色测试文字”进行渲染,“红色测试文字”和“蓝色测试文字”字体,大小变了。
接下来看到的是图片文件下载,此时看到的是两个图片同时开始下载,而且是下载完成后,立即在页面上开始显示,直到所有的图片下载完成。
经过以上的分析,推测IE下载或者渲染顺序可能如下:
IE6下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(但并不是说所有相关联的元素都已经下载完。)在下载过程中,如果遇到某一标签是嵌入文件,并且文件是具有语义解释性 的(例如:JS脚本),那么此时IE的下载过程会启用单独连接进行下载。并且在下载后进行解析,解析(JS中 如有重定义,后定义函数将覆盖前定义函数)过程中,停止页面所有往下元素的下载。
样式文件比较特殊,在其下载完成后,会用样式表对整个页面的进行渲染,下载完成一个渲染一个,后面的样式会覆盖前面的样式。l3.css覆盖了l1.css,l2.css的字体大小,l3.css渲染完成以后页面的“红色测试文字”和“蓝色测试文字”字体变小了。
FF和IE6的渲染存在一些差别,
1、 CSS渲染,FF会把l1.css,l2.css,l3.css合并后再渲染整个页面。IE6会下载一个渲染一个。IE8和FF一样。
2、JS同步执行的时候都会禁止新的资源的下载。但是FF下载JS是并发的,解释执行和IE6一样是根据script标签顺序解释执行。
文件在网络传输上所花费时间。wait = 服务器所花时间 + 网络传输时间
服务器所花时间我们可以用Thread.sleep(5000);来让其休息5s,如下图
由此大概可以计算出 5.01-10 = 0.01秒,这就是大概在网络上所花的时间。HTTP304表示没有变化用本地缓存文件所以除Thread.sleep(5000)服务器耗时外,其它服务器操作几乎可以忽略时间。整个页面的效果图,出来还有渲染时间,现在还没有测试最终效果,也就是从文件下载到本地,到最终渲染完成的时间。也没有更好的方式去测试。