一般我们都会将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代码放在body结束标签之前,打印出来的就是div元素了
所以,通过这个简单的例子我们可以看到,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>
页面是这样的:
一直在执行那个打印1的死循环,后面的body都没有加载渲染出来。所以,这个小例子,我们可以看出,js的下载和执行会阻塞Dom树的构建。
所以,Javascript的加载和执行的特点:
(1)载入后马上执行;
(2)执行时会阻塞页面后续的内容(包括页面的渲染、其它资源的下载)。原因:因为浏览器需要一个稳定的DOM树结构,而JS中很有可能有 代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修 改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现。
减少 JavaScript 对性能的影响的方法:
- 将所有的script标签放到页面底部,也就是body闭合标签之前,这能确保在脚本执行前页面已经完成了DOM树渲染。
- 尽可能地合并脚本。页面中的script标签越少,加载也就越快,响应也越迅速。无论是外链脚本还是内嵌脚本都是如此。
- 采用无阻塞下载 JavaScript 脚本的方法:
(1)使用script标签的 defer 属性(仅适用于 IE 和 Firefox 3.5 以上版本);
(2)使用动态创建的script元素来下载并执行代码;