JS以及CSS对页面的阻塞

1、JS阻塞javascript

   全部的浏览器在下载JS文件的时候,会阻塞页面上的其余活动,包括其余资源的下载以及页面内容的呈现等等,只有当JS下载、解析、执行完,才会进行后面的 操做。在现代的浏览器中CSS资源和图片image资源是并行下载的,在IE6中默认的并行的加载数目是2个,在IE6之后以及其余的浏览器中的默认的并行加载数目是6个。css

在浏览器从服务器接收到HTML文档后,并把HTML在内存中转换为DOM树,在转换节点的过程当中若是引入了CSS文件以及添加了images,则会在文档加载的同时并行的加载CSS文件以及图片。可是JS不同,由于浏览器须要1个稳定的DOM树结构,而JS中颇有可能有代码直接改变了DOM树结构,好比使用document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,须要从新构建DOM树的状况,因此就会阻塞其余的下载和呈现.在没有使用异步加载(async)或者是延迟加载(defer)的状况下,只有在一个JS文件加载解析完后才能加载后面的JS文件。利用延迟脚本和异步脚本能够实现脚本的并行加载。如下讨论都是在没有这两个属性的状况下。html

  (1)内嵌脚本的阻塞java

     直接写在HTML文档中的js代码就是内嵌JS,内嵌脚本无需加载,能够直接执行,因此当页面有内嵌的脚本时,能够直接执行,致使会阻塞全部资源的加载和页面的呈现。bootstrap

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>内嵌JS会阻塞页面上的全部内容的呈现</title>
</head>
<body>
<div>
<ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客园span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li>
</ul>
<span style="color: #800000;"></span>
</div>
<script type="text/javascript">
// 循环5秒钟
var n = Number(new Date());
var n2 = Number(new Date());
while((n2 - n) < (6*1000)){
n2 = Number(new Date());
}
</script>

<ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li>
</ul>

</body>
</html>

上面的内嵌脚不只会阻塞第二个ul的展现,也会阻塞第一个ul的展现,页面在5秒前是一片空白,当延迟结束后才展示全部的内容浏览器

(2)外联脚本阻塞服务器

  外联脚本不同,外联脚本只有当页面加载到该<script>以后才会加载外联脚本,因此外联脚本只会阻塞其后面的内容的呈现以及资源的下载,在下面的代码中,页面会先展现一部份内容,后面一部份内容在5秒后展示app

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>外联JS文件只会阻塞后面的资源的下载和呈现</title>
</head>
<body>
<ul>
    <li>blogjavaspan style="color: #800000;"</li>
    <li>CSDNspan style="color: #800000;"</li>
    <li>博客园span style="color: #800000;"</li>
    <li>ABCspan style="color: #800000;"</li>
    <li>AAAspan style="color: #800000;"</li>
</ul>
<script src="定时.js"></script><!--定时中的代码和上面的延迟函数的内容同样的-->
<ul>
    <li>MSNspan style="color: #800000;"</li>
    <li>GOOGLEspan style="color: #800000;"</li>
    <li>YAHOOspan style="color: #800000;"</li>
</ul>
</body>
</html>

2、嵌入JS致使CSS阻塞加载的问题异步

async

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

fireBug中的时间栈:

谷歌中的事件栈:

在上图中CSS和图片是并行下载的,经过时间线能够看出,后面的图片并无等到CSS文件彻底加载完后在加载。

(2)内嵌脚本致使CSS阻塞页面

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript">
        function a(){};
    </script>
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

fireBug中的时间栈:

 谷歌中的时间栈:

经过上图在狐火中因为内嵌脚本的做用使得图片要等到css彻底加载完后在加载,即CSS阻塞了图片的加载。其实质是由于浏览器会维持HTML中CSS和JS的顺序,即在JS前面出现的CSS文件须要加载、解析完后才会执行后面的内嵌JS,而内嵌JS又会阻塞后面的内容

(2)外联脚本

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link type="text/css" rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap-grid.css" />
    <script type="text/javascript" src="fun.js"></script><!--这里fun中的内容就是a方法-->
</head>
<body>
<img src="http://www.blogjava.net/images/logo.gif" />
<img src="http://csdnimg.cn/www/images/csdnindex_piclogo.gif" />
</body>
</html>

外联脚本会阻塞后面资源的加载,可是在谷歌浏览器中不论是内联仍是外联的脚本均不会阻塞

3、为了避免阻塞页面脚本的放置位置

(1)尽可能合并脚本减小<script>的出现

(2)尽可能使用外联脚本并将脚本放置在<body>底部

(3)使用延迟脚本和异步脚本

(4)内嵌脚本放置在window.onload中执行

相关文章
相关标签/搜索