如何防止JavaScript和HTML阻塞

4

如何防止JavaScript阻止其他JavaScript开始下载?

我在我的网站上有以下内容:

<html>
<body>
....
<script type="text/javascript" src="http://example.com/ex.js"></script>
<script type="text/javascript" src="http://google.com/google-maps.js"></script>
</body>
</html>

当我使用YSlow Firefox插件时,从网络流量选项卡中可以看到,只有在ex.js下载完成后,google.com/google-maps.js JavaScript才开始下载。
问题:如何使ex.jsgoogle-maps.js立即并行下载?
4个回答

3
使用 <script> 元素的 asyncdefer 属性

asyncdefer脚本均会立即开始下载,而不会暂停解析器,并且都支持可选的onload处理程序来解决依赖于脚本的初始化的常见需求。 asyncdefer之间的区别在于脚本执行的时间。每个async脚本在完成下载后的第一次机会执行,在windowload事件之前。这意味着可能(并且很可能)async脚本的执行顺序与它们在页面中出现的顺序不同。另一方面,defer脚本保证按照它们在页面中出现的顺序执行。该执行在解析完全完成之后开始,但在documentDOMContentLoaded事件之前。

  • defer被IE4+,Firefox 3.5+,Chrome 2+和Safari 4+支持。
  • async被Firefox 3.6+,Chrome 7+和Safari 5+支持。 (没有IE支持!)

defer是您最好的选择。脚本将以并行方式下载并以同步方式执行(按顺序)。它也比async更受支持和更可预测。(另请参见这个非常详细的async/defer分析。)

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

2

这在HTML中的内嵌脚本中是正常的。您可以使用以下代码动态添加脚本:

<script type="text/javascript">
    var head  = document.getElementsByTagName("head")[0]; 
    var sTag1 = document.createElement("script");
    var sTag2 = document.createElement("script");
    sTag1.type = sTag2.type = "text/javascript";
    sTag1.src = "http://example.com/ex.js";
    sTag2.src = "http://google.com/google-maps.js";
    head.appendChild(sTag1);
    head.appendChild(sTag2);
</script>

这可能会导致意想不到的结果,因为这些脚本可能不会按照正确的顺序下载和解析,如果第二个脚本从第一个脚本中引用变量或函数,那么这一点就很重要了。
如果你只想让HTML在脚本加载之前加载,请将它们连续放置在HTML文件底部,而不是head标签中。这将在下载和解析脚本之前加载页面。详情请见http://developer.yahoo.net/blog/archives/2007/07/high_performanc_5.html

使用这种方法与@womp推荐的方法相比,有哪些优缺点?代码看起来截然不同。 - Teddy
@Teddy - 看了womp提到的链接,它们在功能上是相同的,但是那篇博客文章使用循环迭代多个脚本源,然后以与我上面的代码类似的方式创建元素。不过它似乎只对Firefox和Opera这样做,而不是Internet Explorer或其他浏览器,对于这些浏览器,它会直接使用writeLn编写HTML。 - Andy E

2

这并不美观,但你可以通过使用JavaScript注入DOM元素来实现脚本的并行下载。

请查看这篇博客文章获取一个可行的示例。


0

JavaScript文件总是按照它们被指定的顺序下载。


我该如何让JS文件并行下载? - Teddy
@Teddy:你不能这么做。这是浏览器的功能,而不是标记语言的功能。如果我没记错的话,Chrome和Safari 4会对外部JavaScript进行一些并行加载,但是你不能强制其他浏览器以这种方式行事。 - Eric Kolb
@Eric Kolb,请查看@womp - 他似乎有一个小脚本,可以强制其他浏览器并行下载。 - Teddy
好吧,这不是我的脚本..但它应该能完成工作。 - womp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接