《高性能Javascript》part1:js文件的加载

来源:互联网 发布:linux应用基础教程 编辑:程序博客网 时间:2024/05/16 16:19

  最近本来想学学node,写点学习心得什么的。看了一两天,发现并不能理解敲打。但是也不能就这么闲着,第一次写博客,就把以前看过的书总结总结吧。。。

  这本书的原文是2010年的,里面的很多东西可能已经有所变化。

  第一章讲的是js文件的加载问题,我们都知道js文件要放在页面的底部,因为下载js文件会阻塞整个页面的解析。但是仅仅把它放在底部还不够,若文件过多或者单个文件过大,还是会影响整个页面的性能。书中给出了几种解决方式,第一种是动态添加脚本

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

  这样做加载脚本的操作会异步执行,因此也可以把多个js文件按顺序压缩到一起进行添加。需要注意的是,当我们用这种方法一个一个添加脚本,脚本最终载入完成的顺序不一定和我们指定的顺序一样。这样做的问题是,我们不知道引入的js文件何时加载完,可以使用load事件来判断。在前面的代码中加一行

script.onload = function(){//加载完成后要做的事};

  这里注意,当动态添加图片时,指定事件处理程序的代码必须放在指定src属性之前,而动态添加脚本不必这样,所以上面的代码也可以放到script.src = "file1.js";这一行的后面。

由于ie8及之前版本不支持load事件,在老版ie中,使用如下代码实现相同效果

var script = document.createElement ("script")
script.type = "text/javascript";
//Internet Explorer
script.onreadystatechange = function(){
if (script.readyState == "loaded" || script.readyState == "complete"){
script.onreadystatechange = null;
//加载完要做的事
}
};
script.src = "file1.js";
document.getElementsByTagName("head")[0].appendChild(script);

第二种方法是通过xhr对象添加脚本,就是ajax用的那个xhr对象,代码如下

var xhr = new XMLHttpRequest();
xhr.open("get", "file1.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);//代码都是直接复制的,对齐什么的我就不搞了,复制过来就这样。

  书上说这样做的缺点是请求的文件必须和页面放在一个域内,不能从CDNs下载,但是script和img元素不是不受跨域限制吗?不懂。。。

  推荐的是第一种方法,使用时先把用来加载代码的那部分js放到页面中,等页面加载完再用这部分代码加载其余的脚本。如下是第一种方法的完全体模式

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_r("head")[0].appendChild(script);
}

  当然,我们平时也不用非得自己写这些东西,书中最后介绍了几个比较好用的代码加载库,比如lazyload,LABjs。也可以学学怎么用它们。

  行了,第一篇就先写这些了。


———————————————————————————————————————————————————


  回过头又看了一下这篇,发现之前没写明白,在此做些补充。

关于为什么要动态添加脚本,我们平时是把脚本放到底部,这样可以让页面加载完后在进行脚本的下载和运行。但是如果脚本太多,在页面加载完展现在用户面前之后,页面依旧会瘫痪一段时间。

而动态添加的脚本,它的下载和执行不会阻塞页面的操作(书上说的,应该是真的),所以动态添加时最完美的解决办法。动态添加脚本要想保证加载顺序,可以用回调函数的方式来实现,只有在优先级高的脚本加载完后,别的脚本再能加载。

1 0