JavaScript:异步加载的脚本,是那些"并行"评估的(竞争条件)吗?

Tim*_*Tim 3 javascript

鉴于我异步(!!)使用异步脚本加载器(将脚本标记写入文档的头部然后将下载文件)加载多个JavaScript文件,这些脚本是否并行评估?

<script>
 var script = document.createElement('script');
 script.src = "library1.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
 <!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library2.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
<!-- Other Markup -->
<script>
 var script = document.createElement('script');
 script.src = "library3.js";
 document.getElementsByTagName('head')[0].appendChild(script); 
</script>
Run Code Online (Sandbox Code Playgroud)

"通常",当HTML文档中有标准脚本标记(正文和头部!?)时,浏览器将停止/完成所有其他活动(下载/页面呈现)并仅处理它遇到的单个脚本标记.这导致"序列化"执行,不会导致任何"竞争条件".

但是通过使用异步加载器技术,插入的脚本标记(在头部中)是否也会导致(最后)到序列化渲染(在下载时),只会评估"当前"脚本或者是否存在其他异步加载的脚本文件将被并行评估,因此容易出现竞争条件?

非常感谢你!!蒂姆

Cre*_*esh 5

尽管脚本将并行下载,但执行它们的顺序并不确定.IE将按照他们完成下载的顺序执行它们,而Firefox按照它们在DOM中附加的顺序执行它们.

这是个问题.例如,假设使用该技术添加脚本A和脚本B. 现在假设脚本A是jQuery,脚本B执行此操作:

$(document).ready(function(){...})
Run Code Online (Sandbox Code Playgroud)

在IE中,如果由于某种原因(例如,网络流量,缓存未命中)脚本B在脚本A之前完成下载,则会被搞砸,因为它将在加载jQuery之前执行.

请参阅此文章以获得更好的解释.

至于解决方案,您可以<script>元素尽可能放在页面尽可能远的位置(例如,在关闭</body>元素之前.虽然这不能保证并行下载,但它确实有助于缓解解决方案正在解决的"阻塞"问题.