load and execute order of scripts
在HTML页面中包含javascript的方法有很多种。我知道以下选项:
- 内联代码或从外部URI加载
- 包括在或标签中[1,2]
- 没有,
defer 或async 属性(只有外部脚本) - 包含在静态源中或由其他脚本动态添加(在不同的分析状态下,使用不同的方法)
不算硬盘上的browserscripts,javascript:uri和
我不太关心快速(并行)加载,我更好奇执行顺序(这可能取决于加载顺序和文档顺序)。是否有一个很好的(跨浏览器)参考,真正涵盖所有案例?例如http://www.websiteoptimization.com/speed/tweak/defer/只处理其中的6个,测试的大多是旧的浏览器。
我担心没有,这是我的具体问题:我有一些(外部)头脚本用于初始化和脚本加载。然后在正文的末尾有两个静态的内联脚本。第一个允许脚本加载器动态地将另一个脚本元素(引用外部JS)附加到主体。第二个静态内联脚本希望使用添加的外部脚本中的JS。它是否可以依赖另一个已被执行(以及为什么是-)?
如果您没有动态加载脚本或将其标记为
异步脚本(不管如何指定为异步)以不可预知的顺序加载和运行。浏览器可以并行加载它们,并且可以自由地按任意顺序运行它们。
多个异步对象之间没有可预测的顺序。如果需要一个可预测的顺序,那么就必须通过注册异步脚本中的加载通知来对其进行编码,并在加载适当的内容时手动对javascript调用进行排序。
动态插入脚本标记时,执行顺序的行为将取决于浏览器。您可以在本文中看到火狐的行为。简而言之,新版本的firefox默认将一个动态添加的脚本标记设置为async,除非脚本标记已设置为其他类型。
带有
带有
这是那篇文章的引言:
script-inserted scripts execute asynchronously in IE and WebKit, but
synchronously in Opera and pre-4.0 Firefox.
HTML5规范的相关部分(对于较新的兼容浏览器)在这里。这里有很多关于异步行为的文章。显然,这个规范不适用于旧的浏览器(或错误确认的浏览器),您可能需要测试这些浏览器的行为来确定。
HTML5规范的引用:
Then, the first of the following options that describes the situation
must be followed:If the element has a src attribute, and the element has a defer
attribute, and the element has been flagged as"parser-inserted", and
the element does not have an async attribute
The element must be added
to the end of the list of scripts that will execute when the document
has finished parsing associated with the Document of the parser that
created the element.The task that the networking task source places on the task queue once
the fetching algorithm has completed must set the element's"ready to
be parser-executed" flag. The parser will handle executing the script.If the element has a src attribute, and the element has been flagged
as"parser-inserted", and the element does not have an async attribute
The element is the pending parsing-blocking script of the Document of
the parser that created the element. (There can only be one such
script per Document at a time.)The task that the networking task source places on the task queue once
the fetching algorithm has completed must set the element's"ready to
be parser-executed" flag. The parser will handle executing the script.If the element does not have a src attribute, and the element has been
flagged as"parser-inserted", and the Document of the HTML parser or
XML parser that created the script element has a style sheet that is
blocking scripts The element is the pending parsing-blocking script of
the Document of the parser that created the element. (There can only
be one such script per Document at a time.)Set the element's"ready to be parser-executed" flag. The parser will
handle executing the script.If the element has a src attribute, does not have an async attribute,
and does not have the"force-async" flag set The element must be added
to the end of the list of scripts that will execute in order as soon
as possible associated with the Document of the script element at the
time the prepare a script algorithm started.The task that the networking task source places on the task queue once
the fetching algorithm has completed must run the following steps:If the element is not now the first element in the list of scripts
that will execute in order as soon as possible to which it was added
above, then mark the element as ready but abort these steps without
executing the script yet.Execution: Execute the script block corresponding to the first script
element in this list of scripts that will execute in order as soon as
possible.Remove the first element from this list of scripts that will execute
in order as soon as possible.If this list of scripts that will execute in order as soon as possible
is still not empty and the first entry has already been marked as
ready, then jump back to the step labeled execution.If the element has a src attribute The element must be added to the
set of scripts that will execute as soon as possible of the Document
of the script element at the time the prepare a script algorithm
started.The task that the networking task source places on the task queue once
the fetching algorithm has completed must execute the script block and
then remove the element from the set of scripts that will execute as
soon as possible.Otherwise The user agent must immediately execute the script block,
even if other scripts are already executing.
浏览器将按找到脚本的顺序执行脚本。如果调用外部脚本,它将阻塞页面,直到脚本被加载和执行。
要测试这一事实:
1 2 3 4 5 6 | // file: test.php sleep(10); die("alert('Done!');"); // HTML file: <script type="text/javascript" src="test.php"> |
动态添加的脚本在附加到文档后立即执行。
要测试这一事实:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <!DOCTYPE HTML> <html> <head> Test </head> <body> <script type="text/javascript"> var s = document.createElement('script'); s.type ="text/javascript"; s.src ="link.js"; // file contains alert("hello!"); document.body.appendChild(s); alert("appended"); <script type="text/javascript"> alert("final"); </body> </html> |
警报顺序为"附加"->"你好!">"最后"
如果在脚本中,您试图访问尚未到达的元素(例如:
总的来说,是的,您可以包括外部脚本,然后访问它们的函数和变量,但是只有当您退出当前的
@addyosmani的精彩总结
不知羞耻地从https://addyosmani.com/blog/script-priorities复制/