标签:
先看一下标准定义的浏览器渲染过程(网上找的):
这里面有几个点需要说明一下:
1.我们知道浏览器的处理过程是解析html生成DOM tree->根据DOM tree和样式表生成render tree->渲染render tree展示。浏览器为了让用户更快的看到页面,所以是边解析html生成局部的DOM tree,浏览器就生成部分render tree然后展示出来。
2.此过程中有两种外部资源是阻塞脚本执行,从而阻塞渲染的,分别是外部js和外部css。外部js是阻塞了DOM tree的生成,因为浏览器需要一个稳固的DOM tree,而js可能破坏这个结构(当然其中也可能会更改样式【注意是样式而不是样式表】,但是这个不阻塞也不会有影响的);外部css样式表也会阻塞脚本的执行,理论上,既然样式表不改变Dom树,也就没有必要停下文档的解析等待它们,然而,存在一个问题,脚本可能在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值,显然这将会导致很多问题,这看起来是个边缘情况,但确实很常见。Firefox在存在样式表还在加载和解析时阻塞所有的脚本,而Chrome只在当脚本试图访问某些可能被未加载的样式表所影响的特定的样式属性时才阻塞这些脚本。
3.其他外部资源是不阻塞渲染的,比如图片,我们能看到很多时候页面大体的框架都呈现出来了,就是图片的位置没有显示出来的情况,等到图片下载下来以后再重新渲染。
现代浏览器的优化:
按照标准的浏览器渲染和下载过程。下面的代码加载外部资源的顺序应该和资源在html中的顺序一致。其中head中添加了一个外部资源请求http://hm.baidu.com/hm.js?a041a0f4ff93aef6aa83f34134331a1d应该在所有样式之前加载
<html> <head> ... <!--百度统计代码--> <script> var _hmt = _hmt || []; (function() { var host=document.location.hostname; if(/lcfarm.com$/ig.test(host)){ var hm = document.createElement("script"); hm.src = "//hm.baidu.com/hm.js?a041a0f4ff93aef6aa83f34134331a1d"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); } })(); </script> <link rel="stylesheet" type="text/css" href="//static.lcfarm.com/pc-dist/pkg/index.html_aio_f9db6a6.css"> <link rel="stylesheet" type="text/css" href="//static.lcfarm.com/pc-dist/common/css/common_530eedd.css"> <link rel="stylesheet" type="text/css" href="//static.lcfarm.com/pc-dist/css/index_8b620da.css"> <link rel="stylesheet" type="text/css" href="//static.lcfarm.com/pc-dist/pkg/index.html_aio_2_2379650.css"> </head> <body> ... <script type="text/javascript" data-loader="" src="//static.lcfarm.com/pc-dist/common/dep/mod_36ad799.js"></script> <script type="text/javascript" data-loader="" src="//static.lcfarm.com/pc-dist/common/dep/jquery_c07f226.js"></script> <script type="text/javascript" src="//static.lcfarm.com/pc-dist/common/js/jquery/jquery.cookie_546183c.js"></script> <script type="text/javascript" src="//static.lcfarm.com/pc-dist/pkg/common_85ea494.js"></script> <script type="text/javascript" src="//static.lcfarm.com/pc-dist/pkg/index.html_aio_350303c.js"></script> </body> </html>
但是实际上在chrome。Firefox、ie8+等浏览器中却发现是如下效果(使用https://www.webpagetest.org/测试)
为什么?这就是预解析(Speculative parsing)
Webkit和Firefox都做了这个优化,当执行脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。需要注意的是,预解析并不改变Dom树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。
如上面的那张图,可以看出在执行脚本的时候与解析了一大堆的外部资源引用,并启动线程下载他们,主线程还在等待hm.js的返回。
浏览器加载和渲染HTML的过程(标准定义的过程以及现代浏览器的优化)
标签:
原文地址:http://www.cnblogs.com/chuaWeb/p/5796405.html