JavaScript的加载性能优化

无论当前JavaScript代码是内嵌还是还是在外链文件中,页面的下载和渲染都必须停下来等待脚本执行完成。JavaScript执行过程耗时越久,浏览器等待响应用户输入的时间就越长。我们可以从以下几个方面进行优化:

1. 改变脚本的位置

  因为脚本的下载和执行,会阻塞其他资源(样式文件或图片)的下载。因此,将<script>标签尽量尽可能放到<body>标签的底部。

2. 组织脚本

  尽量减少页面中的<script>标签;

  尽量将多个js文件合并为一个,减少http的请求;

3. defer, async

     Html4为<script>标签定义了一个扩展属性defer。对应的<script>所对应的文件在解析到时开始下载,直到DOM元素加载完成后执行。

   Html5为<script>标签定义了一个扩展属性async。对应的<script>所对应的文件在解析到时开始下载,下载完成后立即执行。

4. 动态创建<script>元素下载并执行JavaScript.

FireFox, Chrome,Safari,Opera会在下载完成后发出一个onload事件.

var script = document.createElement ("script")
script.type = "text/javascript";

//Firefox, Opera, Chrome, Safari 3+
script.onload = function(){
    alert("Script loaded!");
};

script.src = "script1.js";
document.getElementsByTagName("head")[0].appendChild(script);

IE实现了另一种实现方式,它会发出readystatechange事件。<script>元素有一个readyState属性,它的值随着下载外部文件的过程而改变。
var script = document.createElement("script")
script.type = "text/javascript"; //Internet Explorer
script.onreadystatechange = function(){
  if (script.readyState == "loaded" || script.readyState == "complete"){
    script.onreadystatechange = null;
    alert("Script loaded.");
  }
};
script.src = "script1.js";
document.getElementsByTagName("head")[0].appendChild(script);

为了屏蔽浏览器的不同,可以写一个函数进行封装:
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>的src属性可以设置为另外一个域的文件。这里似乎有一个安全性的问题。

5. 使用XMLHttpRequest对象

创建一个XMLHttpRequest对象下载JavaScript文件,接着用一个动态<script>标签将JavaScript代码注入页面。
var xhr = new XMLHttpRequest();
xhr.open("get", "script1.js", true);
xhr.onreadystatechange = function(){
    if (xhr.readyState == 4){
        if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304){
            var script = document.createElement ("script");
            script.type = "text/javascript";
            script.text = xhr.responseText;
            document.body.appendChild(script);
        }
    }
};
xhr.send(null);

这个方法可以下载不立即执行的JavaScript. 这个代码适用于所有的浏览器。
这个方法的主要限制是页面与JavaScript文件必须放在同一个域里,不能从CDN下载。

 

posted @ 2014-04-06 18:06  临风远望  阅读(192)  评论(0编辑  收藏  举报