Script标签和剧本实行递次 - 文档加载 - 面向浏览器编程

原文: http://pij.robinqu.me/Browser_Scripting/Document_Loading/ScriptTag.html

源代码: https://github.com/RobinQu/Programing-In-Javascript/blob/master/chapters/Browser_Scripting/Document_Loading/ScriptTag.md

  • 本文须要补充更多例子
  • 本文存在讲明,但该网站的Markdown编辑器不支撑,所以没法一般展现,请到原文参考。

Script标签和剧本实行递次

这里细致聊聊和script标签相干的剧本实行递次。

Script标签的默许行动

几个主要特征:

  • script标签(不带deferasync属性)的会阻挠文档衬着。相干剧本会马上下载并实行。
  • document.currentScript能够获得当前正在运转的剧本(Chrome 29+, FF4+)
  • 剧本递次再默许状况下和script标签涌现的递次一致

假定以下简朴代码1,最终会发生三个alert依次为“A”、“B”、“C”。

<!-- HTML Code -->
<script>alert("A");</script>
<script>alert("B");</script>
<script>alert("C");</script>

我们再斟酌有收集要求的状况2

<!-- HTML code -->
<script  src="https://snipt.net/raw/7b08744009c450e07c0bfc1d606fc72e/"></script>
<script  src="https://snipt.net/raw/a2e8c05c1f6fc0e47d259aa899304e89/"></script>
<script  src="https://snipt.net/raw/4fab3017d3d46cbfc4bbd88aab006650/"></script>

三个文件都须要先下载再运转,且第二个文件的尺寸远大于别的两个文件。但结果依然是弹出三个alert,内容分别是”A”、”B”、”C”。

从上面两个例子,能够充足相识到script标签的柱塞式实行。

async属性

async属性是HTML5的新特征3,这意味着其兼容性并不乐观(IE10+)。

async示意该script标签并不柱塞,也不同步实行。浏览器只须要在剧本下载终了后再实行即可——没必要柱塞页面衬着守候该剧本的下载和实行。

以下代码4,会获得三个alert,然则alert的内容分别是”A”,”C”,”B”。

<!-- HTML code -->
<script  src="https://snipt.net/raw/7b08744009c450e07c0bfc1d606fc72e/"></script>
<script  src="https://snipt.net/raw/a2e8c05c1f6fc0e47d259aa899304e89/" async=true></script>
<script  src="https://snipt.net/raw/4fab3017d3d46cbfc4bbd88aab006650/"></script>

能够看到,第二个script标签在到场async并没有阻挠后续文档剖析和剧本实行。

精细精美这个属性发生的原有,其实有大批的剧本加载器在做如许的事变:

var script = document.createElement("script");
script.src = "file.js";
document.body.appendChild(script);

不难想象,经由历程剧本异步插进去的script标签到达的结果和带async属性的script标签是一样的。换句话说,由剧本插进去的script标签默许是async的。

别的,对内联剧本设置async属性是没有意义的,也不发生其他结果。其包括的剧本老是马上实行的。

defer属性

带有defer属性的剧本,同样会推延剧本的实行,而且不会阻挠文档剖析。就犹如这个剧本,安排到了文档的末端(</body>之前)。

以下代码5的宏观征象和加了async属性的例子是一样的,都邑获得”A”、”C”、”B”的三个alert。然则其道理是不一样的。

<!-- HTML code -->
<script  src="https://snipt.net/raw/7b08744009c450e07c0bfc1d606fc72e/"></script>
<script  src="https://snipt.net/raw/a2e8c05c1f6fc0e47d259aa899304e89/" defer=true></script>
<script  src="https://snipt.net/raw/4fab3017d3d46cbfc4bbd88aab006650/"></script>

defer属性是会确保剧本在文档剖析终了后实行的——纵然这个剧本在文档剖析历程中就已下载终了变成可实行的状况,浏览器也会推延这个剧本的实行,直到文档剖析终了6,并在DOMContentLoaded之前7

同时,带有defer的剧本彼此之间,能保证其实行递次。

注重,defer属性并非每一个浏览器支撑,即使支撑的浏览器,也会因为版本不一样致使详细行动不一致。别的,人人能够经由历程将script标签安排到文档末端这类简朴的做法到达defer属性一样的结果。

defer属性早在IE4就被支撑,然则这个defer属性和当代浏览器的行动是有区分的。只要IE10以上,才最先根据范例实行defer属性。

async与defer的影响

参考W3C的官方文档8,defer和async两个属性是能够相互影响的:

There are three possible modes that can be selected using these attributes. If the async attribute is present, then the script will be executed asynchronously, as soon as it is available. If the async attribute is not present but the defer attribute is present, then the script is executed when the page has finished parsing. If neither attribute is present, then the script is fetched and executed immediately, before the user agent continues parsing the page.

简朴的归结:

  • 唯一async属性,剧本会异步实行
  • 唯一defer属性,剧本会在文档剖析终了后实行
  • 两个属性都没有,剧本会被同步下载并实行,时期会柱塞文档剖析

范例里没有提到两种属性都偶然的结果,但这是文档中被许可的。如许的详细结果会在背面议论。

document.write的影响

docuemnt.write许可向翻开的文档流中写入文档内容;内嵌到HTML内里的docuemnt.write能够当场增加文档内容。斟酌到docuemnt.write写入script标签的状况9:

<!-- HTML code -->
<script  src="https://snipt.net/raw/7b08744009c450e07c0bfc1d606fc72e/"></script>
<script>document.write("\<script  src=https://snipt.net/raw/a2e8c05c1f6fc0e47d259aa899304e89 \/\>\<\/script\>");</script>
<script  src="https://snipt.net/raw/4fab3017d3d46cbfc4bbd88aab006650/"></script>

观察到实行递次和一般的script标签没有区分。纵然你插进去的标签带有async或defer,其行动也是没有区分的。

让人纠结的是反过来10运用。因为第二个剧本是经由历程document.write写入的。被耽误的剧本在实行时,document已封闭,document.write是没有任何结果的。所以,不论运用defer照样async,第二个剧本一直没有运转。

浏览器兼容性

defer属性

点击检察

async属性

点击检察

测试用例

TODO

  1. http://t.cn/RvApb3D 

  2. http://t.cn/RvApGke 

  3. http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#attr-script-async 

  4. http://t.cn/RvApq3G 

  5. http://t.cn/RvAp5xj 

  6. http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/ 

  7. https://www.webkit.org/blog/1395/running-scripts-in-webkit/ 

  8. http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#attr-script-defer 

  9. http://t.cn/RvApt7Q 

  10. http://t.cn/RvAptOo 

    原文作者:RobinQu
    原文地址: https://segmentfault.com/a/1190000000515181
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞