脚本加载

js脚本会阻塞页面其他资源的下载,直到其下载、解析、执行完毕。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现.

html、css、图片是可以并行加载的。当浏览器从服务器接收到了HTML文档,并把HTML在内存中转换成DOM树,在转换的过程中如果发现某个节点(node)上引用了CSS或者 IMAGE,就会再发1个request去请求CSS或image,然后继续执行下面的转换,而不需要等待request的返回,当request返回 后,只需要把返回的内容放入到DOM树中对应的位置就OK。

下面的代码会先弹出"head js"对话框,浏览器再继续分析文档DOM结构,此时"Hello World"文本才呈现。然后再弹出"body js"对话框,"Try hard!"文本呈现。

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script>alert("head js")</script>
</head>
<body>
    <h1>Hello World!</h1>
    <script>alert("body js")</script>
<h2>Try hard!</h2>
</body>
</html>

解决方法:

设置<script defer="defer"></script>,脚本会被延迟到整个页面都解析完毕再运行。即告诉浏览器立即下载,但延迟执行。

defer属性只适用于外部脚本,IE4-IE7还支持内联脚本,IE8,FF3.5,Safari5,Chrome会忽略内联脚本的defer属性。

HTML5定义了一个属性async与defer类似,但并不保证它们的先后执行顺序,所以确保它们互不依赖。FF3.6,Safari5,Chrome支持。

还有一种常用的方法,就是把延迟脚本放在页面底部。

最后介绍一种动态脚本方法。

function loadScript(url){
     var script = document.createElement("script");
     script.type = "text/javascript";
     script.src = url;
     document.body.appendChild(script);
}

 

posted @ 2014-08-22 00:08  xjinza  阅读(302)  评论(0编辑  收藏  举报