【发布时间】:2010-05-10 16:02:47
【问题描述】:
我在页面加载后动态添加一些<script> 标签到head 元素。我知道脚本是异步加载的,但我可以期望它们按照添加的顺序进行解析吗?
我在 Firefox 中看到了预期的行为,但在 Safari 或 Chrome 中没有。查看 Chrome 开发人员工具和 Firebug 中的文档,均显示以下内容 -
<html>
<head>
...
<script type="text/javascript" src="A.js"></script>
<script type="text/javascript" src="B.js"></script>
</head>
...
</html>
但是查看资源加载视图,chrome 似乎会解析服务器首先返回的内容,而 firebug 总是按照添加脚本标签的顺序加载它们,即使 B 首先从服务器返回。
我应该期望 Chrome/Safari 以指定的顺序解析文件吗?在 OS X 10.6.3 上使用 Chrome 5.0.375.29 测试版
编辑(10/5/10):当我说解析时,我的意思是执行 - 可以看到积极解析的许多好处 - thx rikh
编辑(2010 年 11 月 5 日):好的,所以我按照下面 juandopazo 的思路进行了测试。但是我添加了一些东西,包括
- 直接使用javascript将脚本元素添加到头部。 (测试 A -> D)
- 使用 jquery 的 append() 方法将脚本元素添加到头部。 (测试 E -> H)
- 使用 jquery 的 getScript() 方法“加载”脚本。 (测试 I -> L)
我还尝试了脚本标签上“异步”和“延迟”属性的所有组合。
您可以在此处访问测试 - http://dyn-script-load.appspot.com/,并查看源代码以了解其工作原理。加载的脚本只需调用 update() 函数。
首先要注意的是,只有上面的第 1 和第 3 方法并行操作 - 第 2 方法按顺序执行请求。你可以在这里看到这个图表 -
图 1 - 请求生命周期图
Request lifecycle Graph http://dyn-script-load.appspot.com/images/dynScriptGraph.png
有趣的是,jquery append() 方法也阻塞了 getScript() 调用——你可以看到它们都不会执行,直到所有 append() 调用都完成,然后它们都并行运行。最后要注意的是,jQuery append() 方法一旦执行就会从文档头部删除脚本标签。只有第一种方法将脚本标签留在文档中。
Chrome 结果
结果是 Chrome 总是执行第一个返回的脚本,不管测试如何。这意味着所有测试都“失败”,除了 jQuery append() 方法。
图 2 - Chrome 5.0.375.29 测试版结果
Chrome Results http://dyn-script-load.appspot.com/images/chromeDynScript.png
火狐搜索结果
然而,在 firefox 上,如果使用第一种方法,并且 async 为 false(即未设置),那么脚本将可靠地按顺序执行。
图 3 - FF 3.6.3 结果
FF Results http://dyn-script-load.appspot.com/images/ffDynScript.png
请注意,Safari 似乎以与 Chrome 相同的方式提供不同的结果,这是有道理的。
另外,我在慢速脚本上只有 500 毫秒的延迟,只是为了减少开始->结束时间。您可能需要刷新几次才能看到 Chrome 和 Safari 都失败了。
在我看来,如果没有这样做的方法,我们就没有利用并行检索数据的能力,我们没有理由不应该这样做(如 firefox 所示)。
【问题讨论】:
-
我已将此作为 chrome 问题寄存器中的错误提出 - code.google.com/p/chromium/issues/detail?id=46109
标签: javascript dynamic-script-loading