一般我们都会将script标签放在body结束标签之前,原因如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>测试js代码位置</title>
    <script type="text/javascript">
        var item = document.getElementById("item");
        cosole.log(item);
    </script>

</head>
<body>
    <div id="item" width="100px" height="100px">
        你好
    </div>

</body>
</html>

上述代码中有一段js代码,要在控制台打印一个元素,我把script标签放在head里,控制台里打印出来的是null。 

js 获取所有span标签的values js获取script标签_加载

 

我又把js代码放在body结束标签之前,打印出来的就是div元素了 

js 获取所有span标签的values js获取script标签_html_02

所以,通过这个简单的例子我们可以看到,js代码在加载完后,是立即执行的。 
我又做了一个测试,在js代码里面写了一个死循环,把它放在head标签中,

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>测试js代码位置</title>
    <script type="text/javascript">
        var item = document.getElementById("item");
        while(true){
            console.log(1);
        }
    </script>   
</head>
<body>
    <div id="item" width="100px" height="100px">
        你好
    </div>  
</body>
</html>

页面是这样的: 

js 获取所有span标签的values js获取script标签_js代码_03

一直在执行那个打印1的死循环,后面的body都没有加载渲染出来。所以,这个小例子,我们可以看出,js的下载和执行会阻塞Dom树的构建。

所以,Javascript的加载和执行的特点: 
(1)载入后马上执行; 

(2)执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)。原因:因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有 代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修 改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。

减少 JavaScript 对性能的影响的方法:

  1. 将所有的script标签放到页面底部,也就是body闭合标签之前,这能确保在脚本执行前页面已经完成了DOM树渲染。
  2. 尽可能地合并脚本。页面中的script标签越少,加载也就越快,响应也越迅速。无论是外链脚本还是内嵌脚本都是如此。
  3. 采用无阻塞下载 JavaScript 脚本的方法: 
    (1)使用script标签的 defer 属性(仅适用于 IE 和 Firefox 3.5 以上版本); 
    (2)使用动态创建的script元素来下载并执行代码;