是否应该订购动态脚本? [英] Dynamic script addition should be ordered?

查看:148
本文介绍了是否应该订购动态脚本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在页面加载后动态地向head元素添加一些< script> 标记。我理解脚本是异步加载的,但是我可以期望它们按照添加顺序进行解析吗?

I'm adding some <script> tags dynamically to the head element after page load. I understand the scripts are loaded asynchronously, but can I expect them to be parsed in the order they are added?

我在Firefox中看到了预期的行为,但没有在Safari或Chrome中。查看Chrome开发人员工具和Firebug中的文档,两者都显示以下内容 -

I'm seeing the expected behaviour in Firefox, but not in Safari or Chrome. Looking at the document in Chrome developer tools and Firebug, both show the following -

<html>
  <head>
    ...
    <script type="text/javascript" src="A.js"></script>
    <script type="text/javascript" src="B.js"></script>
  </head>
  ...
</html>

然而,在查看资源加载视图时,chrome似乎会解析从服务器返回的任何一个,而firebug总是按照添加脚本标签的顺序加载它们,即使首先从服务器返回B.

However looking at the resource loading view, chrome seems to parse whichever is returned first from the server, while firebug always loads them in the order the script tags were added, even when B is returned first from the server.

我是否希望Chrome / Safari解析文件中的文件指定的订单?在OS X 10.6.3上使用Chrome 5.0.375.29测试版

Should I expect Chrome/Safari to parse the files in the specified order? Using Chrome 5.0.375.29 beta on OS X 10.6.3

编辑(10/5/10):当我说解析时,我的意思是执行 - 可以看到很多好处积极的解析 - thx rikh

EDIT (10/5/10): When I say parse, I mean execute - can see many benefits of aggressive parsing - thx rikh

编辑(11/5/10):好的,所以我按照下面的juandopazo进行测试。但是我添加了一些组合,包括

EDIT (11/5/10): Ok so I put together a test along the lines of that by juandopazo below. However I have added a combination of things, including


  1. 使用javascript直接将脚本元素添加到头部。 (测试A - > D)

  2. 使用jquery的append()方法将脚本元素添加到头部。 (测试E - > H)

  3. 使用jquery的getScript()方法'加载'脚本。 (测试I - > L)

我还尝试了脚本标签上'async'和'defer'属性的所有组合。

I also tried all combination of the 'async' and 'defer' attributes on the script tags.

您可以在此处访问测试 - http: //dyn-script-load.appspot.com/ ,查看源代码以了解其工作原理。加载的脚本只需调用update()函数。

You can access the test here - http://dyn-script-load.appspot.com/, and view source to see how it works. The loaded scripts simply call the update() function.

首先要注意的是,上面只有第一和第三种方法并行运行 - 第二种方法顺序执行。你可以在这里看到这个图 -

The first thing to note, is that only the 1st and 3rd methods above operate in parallel - the 2nd executes requests sequentially. You can see a graph of this here -

图1 - 请求生命周期图 -
请求生命周期图http://dyn-script-load.appspot.com/images/dynScriptGraph.png

Image 1 - Graph of Request Lifecycle
Request lifecycle Graph http://dyn-script-load.appspot.com/images/dynScriptGraph.png

jquery append()方法也阻止了getScript()调用也很有趣 - 你可以看到在所有append()调用完成之前它们都没有执行,然后它们都是并行运行。关于这一点的最后一点是,jQuery append()方法在执行后显然会从文档头中删除脚本标记。只有第一种方法会在文档中留下脚本标记。

It's also interesting that the jquery append() approach also blocks getScript() calls - you can see that none of them execute until all of the append() calls are complete, and then they all run in parallel. Final note on this is that the jQuery append() method apparently removes the script tags from the document head once they have executed. Only the first method leaves the script tags in the document.

Chrome结果

结果是Chrome始终执行第一个要返回的脚本,无论测试如何。这意味着所有测试'失败',除了jQuery append()方法。

The results are that Chrome always executes the first script to return, regardless of the test. This means all the test 'fail', except the jQuery append() method.

图2 - Chrome 5.0.375.29 beta结果

Chrome结果http://dyn-script-load.appspot.com/images/chromeDynScript.png

Image 2 - Chrome 5.0.375.29 beta Results
Chrome Results http://dyn-script-load.appspot.com/images/chromeDynScript.png

Firefox结果

然而,在Firefox上,它出现了如果使用第一个方法,并且async为false(即未设置),则脚本将按顺序可靠地执行。

On firefox, however, it appears that if the first method is used, and async is false (i.e. not set), then the scripts will reliably execute in order.

图3 - FF 3.6.3结果

FF结果http:// dyn-script-load。 appspot.com/images/ffDynScript.png

Image 3 - FF 3.6.3 Results
FF Results http://dyn-script-load.appspot.com/images/ffDynScript.png

请注意,Safari似乎以与Chrome相同的方式提供不同的结果,这是有道理的。

Note that Safari seems to give varied results in the same manner as Chrome, which makes sense.

另外,我在慢速脚本上只有500毫秒的延迟,只是为了保持开始 - >结束时间。您可能需要刷新几次才能看到Chrome和Safari在所有内容上都失败。

Also, I only have a 500ms delay on the slow script, just to keep the start->finish time down. You may have to refresh a couple of times to see Chrome and Safari fail on everything.

在我看来,如果没有这样做的方法,我们就没有利用并行检索数据的能力,没有理由我们不应该(如firefox所示)。

It seems to me that without a method for doing this, we are not taking advantage of the ability to retrieve data in parallel, and there is no reason why we shouldn't (as firefox shows).

推荐答案

很抱歉回答我自己的问题,但它已经有一段时间了,我们确实提出了一个解决方案。我们想出的是将javascript作为json对象中包含的文本同时加载,然后在加载它们之后使用eval()以正确的顺序执行它们。并发加载加有序执行。根据您的使用情况,您可能不需要json。粗略地说,这里有一些代码显示我们做了什么 -

Sorry for answering my own question, but its been a while and we did come up with a solution. What we came up with was to load the javascript concurrently as text contained in a json object, and then used eval() once they were all loaded to execute them in the correct order. Concurrent load plus ordered execution. Depending on your use case you may not need the json. Roughly, here is some code that shows what we did -

// 'requests' is an array of url's to javascript resources
var loadCounter = requests.length;
var results = {};

for(var i = 0; i < requests.length; i++) {
   $.getJSON(requests[i], function(result) {
      results[result.id] = result;
      ...
      if(--loadCounter == 0) finish();
   });
}

function finish() {
  // This is not ordered - modify the algorithm to reflect the order you want
  for(var resultId in results) eval(results[resultId].jsString);
}

这篇关于是否应该订购动态脚本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆