您好,欢迎访问一九零五行业门户网

加载 Javascript 最佳实践_javascript技巧

相信很多与页面打过交道的同学都对 yahoo 的 best practices for speeding up your web site 不陌生。而这 35 条最佳实践中,对 javascript 的加载顺序的要求是:put scripts at the bottom。因为根据 http/1.1 specification 看来,在同一时间加载两个文件是最理想的,而 javascript 脚本会阻碍平行下载。steve 说那是 2008 – 2009 那个时代用的。现在,加载 javascript 已经有了革命性的化变。
在开讲之前,有一个必须解决的问题是:为什么我们要把 js 文件放在
之前的最底部。根本原因是,它不能平行下载。而其实并不是所有浏览器都不支持。现在大部分浏览器都支持 script 的平行下载,除了老掉牙的 ie6&7、firefox 2&3.0、 safari 3、chrome 1。但我们最熟悉的老掉牙同学 ie6 (或以ie为核的那些壳)还是中国(甚至世界上)市场上占用率最高的浏览器,因此我们需要一个折衷的方案。
一、分析我们有6种方法可以实现平行(non-blocking)下载:
xhr eval – 用 xhr 下载,并 eval() 执行 responsetext.。 xhr injection – 用 xhr 下载,在页面中动态创建一个 script 元素,并将 responsetext 作为其 text 。 script in iframe – 把脚本放在 html 中,使用 ifame  来下载它。 script dom element – 动态创建一个 script 元素,把 src 指向脚本url. script defer – 给 script 标添加 defer 属性 document.write script tag – 利用 document.write 把 添加到 html 中。但这个只对 ie 有效。 兼容性可看下图:
techniqueparallel downloadsdifferexisting scriptsbusy indicatorsensures ordersize (bytes)
xhr eval ie, ff, saf, chr, op no no saf, chr - ~500
xhr injection ie, ff, saf, chr, op no yes saf, chr - ~500
script in iframe ie, ff, saf, chr, op no no ie, ff, saf, chr - ~50
script dom element ie, ff, saf, chr, op yes yes ff, saf, chr ff, op ~200
script defer ie, saf4, chr2, ff3.1 yes yes ie, ff, saf, chr, op ie, ff, saf, chr, op ~50
document.write script tag ie, saf4, chr2, op yes yes ie, ff, saf, chr, op ie, ff, saf, chr, op ~100
二、方案对于究竟应该使用哪种方案。这完全取决于你需要自身的需要。这张图描述了什么时候使用什么方法:
从总体上看来,script dom element 是比较好的方案。ncz 的博客上提过,目前最好的技术是:
创建两个 javascript  文件。第一个文件只提供动态下载 javascript 的代码,第二个文件则包含所有其他页面所需脚本的文件。 像 在页部( 之前)引入第一个文件。 创建第二个 来执行下载第二个 javascript 文件的函数和其他的初始化代码。 三、实现代码根据上面的提到的技术。ncz 推荐第一个文件只包含相应的实现第二个文件动态加载的代码:
复制代码 代码如下:
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);
}
然后,我们可以在页面中这样做:
复制代码 代码如下:
在 html5 上,我们可以使用 async 属性。这个 html 属性的作用正是我们需要的 non-blocking 下载技术。虽然目前支持的浏览器并不多(似乎只有 firefox 3.6+ ?),但给需要平行下载的 javascript(按照方案看来,一般是第一个 js 文件) 加上这个属性,也不会影响其他不支持的浏览器,所以,是推荐使用的。
复制代码 代码如下:
四、实践
yui3 的 loader 使用了 ncz 的这样的方法。而在支付宝。我们也使用了类似的方法。这里简单说一下。
复制代码 代码如下:
在使用的时候,再利用 loader.use() 来实现代码的动态加载。当然,这里不仅仅是动态加载,还有一定的缓存机制在里面。建议你查看相关的 combo 服务的技术。目前支付宝前端架构组的工友们,已经在这一块取得了一些不错的进展(根据测试报告,速度是非常不错的,可能会在适当的时候开源出来)。
五、总结
前端性能优化方面。还有很多东西可以做。并且,随着 html5 技术的出现和 javascript 技术的不断创新,相信还有更多东西是值得期待。前端们,加油吧,未来有很多东西应该是由你来主导的。
reference:
loading scripts without blocking the best way to load external javascript evolution of script loading what is a non-blocking script? html5 – scripting: async attribute
其它类似信息

推荐信息