推迟浏览器上的脚本和执行顺序

时间:2015-09-05 12:54:08

标签: javascript html5

我一直在为我的一个项目的HEAD部分中使用的外部脚本添加defer属性。我查询了多个延迟脚本标记的执行顺序。

以下是我的观察,这将有助于我们更好地理解我的查询:

根据http://www.w3.org/TR/html5/scripting-1.html

  

存在defer属性,然后在页面完成解析后执行脚本

defer属性确实有效。但是,我怀疑执行顺序。在FF和Chrome上看起来有所不同。

根据我的项目:

<script defer="defer" src="{SERVER_PATH}/deps.js?1441452359"></script>
<script defer="defer" src="{SERVER_PATH}/script1.js?1440067073"></script>
<script defer="defer" src="{SERVER_PATH}/script2.js?1441451916"></script>

这里,deps.js是大约120kb(gzip)的大文件,而script1-3的常规大小是20-50kb(gzip)。

在Firefox上,延迟编写脚本的执行确实按照外观顺序开始,但不会以相同的顺序完成。除非前一个脚本完成执行,否则在chrome上的位置,下一个脚本的执行不会启动。看起来Chrome很有意义。

为了测试执行顺序,我在每个脚本的第一行和最后一行插入了console.log,例如在deps.js

console.log("Execution Start: deps");
// minified deps script content.
console.log("Execution End: deps");

Firefox下的控制台输出下方:

Execution Start: deps
Execution Start: script1
Execution Start: script2
// Script Error as script1 needs deps to render completely.
// Script Error as script2 needs deps to render completely.
Execution End: deps

Chrome控制台输出下方:

Execution Start: deps
Execution End: deps
Execution Start: script1
Execution End: script1
Execution Start: script2
Execution End: script2

但是,FF上的行为并不总是如上所示。有时它确实像Chrome一样工作。它看起来像只是Firefox的问题。或者,可能是因为deps.js文件很重且缩小并且需要时间来渲染。

任何有类似经历的人都可以帮助我吗?如果需要任何其他信息,请告诉我。

PS:其他解决方案,例如,移动页面底部的脚本不是我现在正在看的东西。

2 个答案:

答案 0 :(得分:6)

HTML5.0规范说:

  

如果元素具有src属性,并且元素具有defer属性,并且该元素已标记为“parser-inserted”,并且该元素没有async属性

     

必须将元素添加到脚本列表的末尾,这些脚本将在文档完成与创建元素的解析器的Document相关联的解析时执行。

     

一旦获取算法完成,网络任务源在任务队列上放置的任务必须设置元素的“准备好解析器执行”标志。解析器将处理执行脚本。

所以它确实说它推迟了脚本执行,直到解析了相关的Document,它还说它被推入列表中。因此,列表的顺序应该是在解析插入脚本顺序时。

然而,第二部分让我担心。它基本上说它只会被标记为执行,直到网络任务finsihed下载脚本。然后......“解析器将处理执行脚本”。

我在规范中找不到的是文档解析后的脚本执行情况。它是否继续以列表顺序执行脚本,因为它们“准备好被解析器执行”?或者它会等到列表中的所有脚本“准备好执行解析器”然后执行它们。

规范(步骤15):http://www.w3.org/TR/html5/scripting-1.html#script-processing-src-prepare

答案 1 :(得分:0)

我认为除非“执行结束”日志发生在与“执行开始”日志不同的事件循环中,否则这是不可能的。

你能确保我们吗?否则就意味着Firefix在这里做了一些多线程,而且正如我们所知,JS没有支持。