并发下载javascript

发布者: seasun

越来越多的网站演化成了web2.0应用程序,javascript文件也随之增加,但javascript对网站的性能有负面影响。 在主流浏览器(ie6,7)里javascript会从两个方面阻碍页面呈现:

  • script标签下面的网页资源在script加载完之前会停止请求、下载。
  • script标签下面的html元素在script加载完之前会停止渲染。


这个demo说 明了这两种情况。demo页面里包含两个外部javascript文件 接下来是图片、css、和iframe,下面的http 瀑布图表是在ie7下首次访问demo页的情况。从图上可以看到:第一个script标签阻碍了它下面所有资源的下载,接着第二个script标签又 阻碍了所有下载,最后img css 和iframe 并行下载。 同时注意页面渲染,你会发现script标签上面的段落文本瞬间就呈现了,然而其他的html元素在两个script加载完之后才一并显示 出来。

在ie6/7 firefox2/3 Safari3 Chrome1 和 opera下 script标签会阻碍下载
在ie6/7 firefox2/3 Safari3 Chrome1 和 opera下 script标签会阻碍下载

浏览器是单线程的,因此在script执行的时候不下载其他资源是可以理解的,但没有理由让浏览器在script下载的时候阻碍其他资源的下载,还好最新的浏览器(ie8,safari 4,chrome 2)已经 意识到这点了。下面的图标是在ie8下首次访问刚才的demo页时的http瀑布图, 从图中可以看到script的确是并行下载,而且css文件也与script一起并行下载。但是图片和iframe依然被阻碍下载。

虽然在ie8,safari4,chrome2下script可以并发,但依然阻碍了其他资源的下载
虽然在ie8,safari4,chrome2下script可以并发,但依然阻碍了其他资源的下载

幸运的是,有一些方法可以使script标签不会堵塞任何其他资源的下载,即使在老一些的浏览器里。不幸的是开发人员要做更多的工作。

这里有6种方法可以使script与其他资源并行下载:

  • XHR eval — 通过XHR(XMLHttpRequest 对象)下载script,然后用eval方法执行XHR的responseText
  • XHR Injection — 通过XHR下载script,然后建立一个script标签并把它插入文档中(body或者head标签内),接着把script标签的text属性设置为XHR的responseText的值
  • XHR in Iframe — 把script标签放到一个iframe里,通过iframe下载它
  • Script DOM Element — 创建script标签并把它的src属性指向你的脚本地址
  • Script Defer — 添加script标签的defer属性,这个只在ie中有效,但firefox3.1也支持这个属性了
  • 使用document.write方法在页面中写入<script src="">,这个只在ie里有效

你可以通过Cuzillion查看各个方法的使用例子。下面 的表格是对各个方法的总结,通过表格我们可以看到各个方法之间有一些很重要的差异。 虽然Script Defer和document.write Script标签比较混乱(mixed),但大部分方法都实现了并行下载。一些方法不能跨浏览器工作,还有一些方法需要更改你现存的代码才能正常工作。还 有一个不被大家广泛讨论的区别 就是是否会引发浏览器的示忙器[busy indicator](状态栏,任务栏,标签图标,鼠标指针).如果你下载的多个script相互依赖,那么还需要这个方法可以保持多个脚本的下载执行顺 序。

Technique 方法 Parallel Downloads 是否并行下载 Domains can Differ 可否跨域 Existing Scripts 是否需要更改现有脚本 Busy Indicators是否出现示忙器 Ensures Order 是否确保顺序 Size (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

现在的问题是哪种方法才是最好的?其实这个需要具体情况具体分析。下面的树形结构图是可以引导你找到最合适的方法,他并没有看起来的复杂。只有三个关键变量来决定结果:是否需要跨域,是否需要确保执行顺序,是否需要触发示忙器。

这下好了,如果把这个选择逻辑包装在流行的HTML 模板语言(PHP,Python,Perl等等)里,你只需要调用一个函数就能确保使用了最佳方法。

在多数情况下,Script DOM Element是最好的选择。它可以在所有浏览器下工作,不存在跨域问题,而且容易实现,但有一点要记住:他不能在所有浏览器下都确保执行顺序。如果你有 多个相互依赖的script,那么你需要合并它们,或者使用其方法。 如果你有一些内联脚本需要在外部脚本执行后才能执行,那就需要同步(synchronize)他们了。我把它称作”coupling”,Coupling Asynchronous Scripts 这篇文章介绍了一些目前可以实现“coupling”的方法。

转载请标注编辑来源:并发下载javascript

我想网 板凳 编辑

Tags:

分享
QQ书签
百度搜藏
Del.icio.us
Google书签
和讯网摘
天极网摘

回复已关闭.