如果async属性用于加载<head>中的非阻塞<script>,则保证在body.readyState =='loaded'

时间:2015-05-06 18:09:09

标签: javascript html

如果没有异步延迟属性,JavaScript的加载会阻止浏览器,并且始终会加载&lt; head&gt; 中加载的所有脚本加载dom之前和body.readyState =='loaded'。

&#xA;&#xA;

我的问题特定于使用 async 属性来允许&lt; head&gt; 中的非阻止&lt; script&gt; 。然后,一些浏览器可以在仍在检索javascript的同时开始呈现DOM。我发现在&lt; head&gt; 完成&lt; head&gt; 中的异步 JavaScript加载之前,Chrome肯定会进行渲染。

&#xA;&#xA ;

是否这些异步加载了脚本,因此&lt; head&gt; 保证在body.readyState =='loaded'和传统的dom ready javascript之前加载执行了吗?

&#xA;&#xA;

我可以在瀑布中使用Chrome,Firefox和IE11进行确认,在我的测试用例中实际上,onload处理总是在所有JavaScript加载后发生,并立即执行之后在某些情况下,给人的印象是,在当前的浏览器中, async 并没有打破JavaScript在身体状态发生变化之前加载的假设。

&#xA;&#xA;

然而,这是轶事证据,我正在寻找的是关于浏览器架构的标准参考或参考/推理,它为在大型javascript中加载的大量javascript提供了舒适性。 &lt; head&gt; 异步和小&lt; body&gt; 我找不到&lt; body&gt; 完成加载并在&lt; head&gt; 之前加载状态,原因是使用非阻塞异步脚本加载。

&#xA; { {66}} {{11}} 30084428 {{22}} {{33}} {{44}} {{55}}

List# remove() 将有所帮助:

&#xA;&#xA;
  List&lt; String&gt; cards = new ArrayList&lt;&gt;();&#xA; for(char suit:“♥♦♠♣”.toCharArray())&#xA; for(char rank:“23456789TJQKA”.toCharArray())&#xA; cards.add(String.valueOf(rank)+ String.valueOf(suit));&#xA;&#xA; Collections.shuffle(cards);&#xA; System.out.println(cards.remove(0) ); // Q♥//&#xA;  
&#xA;

2 个答案:

答案 0 :(得分:2)

readyState实际上是由文档实现的,因此&lt; body&gt; 在完整文档时只有一个readyState为“loaded”(&lt; head&gt; 和&lt; body&gt; )已加载。使用 async 属性在&lt; head&gt; 中加载JavaScript是安全的,因为所有JavaScript都会在&lt; body&gt; 之前加载,或实际上任何东西,似乎都是“装满”。

&lt; body&gt; 被要求提供readyState时,请求将由其parentNode(即文档)进行响应。 Document implements readyState

启动负载处理的代码是:

var body = document.getElementsByTagName('BODY')[0];
if (body && body.readyState == 'loaded')
    { ... }

所以是的,保证即使是异步JavaScript文件也会在测试&lt; body&gt; 的readyState接收'已加载'的任何加载处理之前完全加载。

然而,它会更清楚,只是要求文件提供readyState。

非常感谢@Bergi在对该问题的评论中指出,它实际上是实现readyState和查找文档的文档:

https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

答案 1 :(得分:0)

当你想知道你的html的一部分将首先被渲染时,有很多事情需要考虑。

  • 正在加载的脚本的大小
  • 文档其余部分的大小
  • 浏览器用于优化内容加载的技术

有些浏览器使用推测性解析来继续加载,即使它找到了阻止脚本。根据推测加载是否成功,浏览器将使用已经检索过的内容,而不是继续呈现所请求的文档。

您可以在mozilla docs

中详细了解推测性解析

例如,如果您有一个巨大的脚本,比如说使用async属性的完整spa应用程序,很可能您的文档将在加载脚本完成之前呈现,但这并不意味着将触发加载的事件。 / p>

主体的readyState在加载所有资源(脚本,样式等)后将更改为“已加载”。读取下载或失败时加载(也包括超时)。您的页面也被视为此资产之一,因此只有在满足所有条件的情况下才会发生此事件。 文档的头部也是页面的一部分,需要在文档声明为就绪并且触发onload事件之前下载。

另一方面,javascript执行是另一回事。使用async属性仅保证浏览器将继续解析文档,并且执行脚本后,可以随时下载。您的文档可能已经下载或未下载,具体取决于剩余内容的数量。还有可能已经执行了其他脚本,这将延迟脚本的执行。

延迟属性不是标准,也不能用作保证。

来自文档

  

此布尔属性设置为向浏览器指示在解析文档后要执行脚本。由于所有其他主流浏览器尚未实现此功能,因此作者不应假设脚本的执行实际上将被延迟。不应在没有src属性的脚本上使用defer属性。从Gecko 1.9.2开始,在没有src属性的脚本上会忽略defer属性。但是,在Gecko 1.9.1中,如果设置了defer属性,甚至内联脚本也会延迟。

最后,您应该注意,并非所有浏览器都支持async属性,如果从较旧的浏览器请求您的页面,则无效。