script标签加载优化

HTMLscript标签加载问题

HTML文档为一行一行从上往下加载。当加载到script标签时会停下所有加载等待script加载完毕,当script放在head标签中时,用户加载网页时会先加载script标签,使得body中的内容没法第一时间加载,导致页面处在一片空白状态下,直到script加载完毕。

在头文件的script全部加载完毕前浏览器会处于阻塞状态,而页面内容都在body标签中,如果将script标签全部放在head标签中会导致用户在script加载完毕前处于空白界面无法进行交互。

 

解决办法:script放在body标签底部

 

为了避免这种情况应该尽量将script放在body标签的底部,先加载界面内容再加载script

 

发起http请求会有时间损耗,会导致下载一个100kb的文件所需时间小于下载425kb的文件所需时间。所以需要尽量将外联js文件合并,减少下载次数。但需要注意的是,js会阻塞浏览器,虽然一次下载完所有的js文件会减少http的时间损耗,但是js文件越大阻塞浏览器的时间就越大。所以好一点的办法就是逐步添加script。具体实现方法如下所示。

 

1. 延期脚本

 

Html4script增加了一种新的属性defer,可以使script延期加载。

 

 <script type="text/javascript" src="test.js" defer> </script>

 

 

 

2. 动态脚本元素

Dom允许动态加载脚本,我们可以动态加载script标签。

 

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "test.js";
document.getElementsByTagName("head")[0].appendChild(script);

 

此文件当元素添加到文档中后会立刻启动下载,此技术重点在于无论在何处下载,文件的下载和运行都不会阻塞页面其他内容

动态添加元素在加载完毕后会发出一个load事件。

 

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "test.js";
script.onload = function() {
   alert("script is readly");
}
document.getElementsByTagName("head")[0].appendChild(script);

ie没有onload事件。有差不多功能的onreadystatechange事件

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "test.js";
script.onreadystatechange = function() {
    if (script.readyState == "loaded" || script.readyState == "complete"){
      script.onreadystatechange = null;
      alert("script is readly");
    }
}

为了兼容,所以将两个函数整合成如下函数

function loadScript(url, callback){
    var script = document.createElement ("script")
    script.type = "text/javascript";
    if (script.readyState){ //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" || script.readyState == "complete"){
                script.onreadystatechange = null;
                callback();
            }
        };
    } else { //Others
        script.onload = function(){
            callback();
        };
    }
    script.src = url;
    document.getElementsByTagName("head")[0].appendChild(script);
}

在使用时可以直接使用script下载仅仅含有loadScriptjs文件,然后用loadScript函数去下载其他标签。

 

<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript">
loadScript("test.js", function(){
    alert('test alert ready')
});
</script>

 

 

 

 

 

 

posted @ 2016-05-07 13:58  地雷  阅读(478)  评论(0编辑  收藏  举报