为什么它显示为延迟的async和async?获得“dom解析事件”吧!但是没有?

问题描述 投票:0回答:1

我有一个装载机,想要研究异步和延迟时间。它是动态插入的外部脚本标记 - 无内联延迟。

起初我理解为什么异步表现为延迟 - 它在DOMContentLoaded之后执行。

使用2000个DOM元素,异步开始显示它可以在DOMContentLoaded之前执行。它从本地驱动器加载。通过从主机获取,在等待响应时执行脚本异步更有意义。这样才行。

然后我改为测试延迟和surprice ..现在我与笑话斗争为什么defer表现为异步 - 在DOMContentLoaded之前执行!

使用超过30秒的100000个DOM元素,脚本执行仍然发生在DOMContentLoaded之前。怎么了?

这是我测试过的相关部件......

loader.js

window.addEventListener('DOMContentLoaded', function() {
  console.log("DOMContentLoaded");
});


  var s = document.head.appendChild(document.createElement('script'))
//  s.async = true; s.defer = false;
  s.async = false; s.defer = true;
  s.src = "script.js"
  console.log("Fetch script");

的script.js

console.log("Execute script");

的index.html

<html>
  <head>
    <script src="loader.js"></script>
  </head>
  <body>

    <script>  window.ti = performance.now() </script>

    --- put here every html you can find ---

    <script>
      var n = document.getElementsByTagName('*').length
      var t = parseInt(performance.now() - ti) / 1000
      document.write("<br>Parsed " + n + " elements in " + t + " s ")
    </script>

  </body>
</html>

FF和Chrome控制台

Fetch script
Execute script
DOMContentLoaded

在准备好使用DOM之前,永远不应该执行延迟脚本。 现在我们有一个案例,在DOM出现在屏幕上之前,DOMContentLoaded会触发。怎么样?


编辑#1

当心DOMContentLoaded - 我想要“解析dom内容”!!! (这就是代码中的错误 - 或者在我看来) 纠正(感谢Pointy) - 用我的话来说......

在解析dom后执行延迟脚本,但dom仍在加载..当延迟脚本和最终事件完成时,DOMContentLoaded将触发。

所以它是我需要的某种“DOMContentParsed”。我找到的最好的是readystatechange事件和document.readyState ...

让我们用这一行扩展loader.js:

s.onload = function(){ console.log(document.readyState) }

有足够的dom,它在Chrome和Firefox控制台中显示:

Fetch script
Execute script
loading
DOMContentLoaded

这意味着在DOM is loading时执行延迟脚本!是的 - 它正在加载,直到DOMContentLoaded。遗憾的是,readyState没有告诉WHEN dom被解析了!我也试过..

document.addEventListener('readystatechange', function() {
  console.log(">>" + document.readyState); 
});

这不会触发“加载”,因为它已经被解雇了,但它说“交互式”AFTER延迟脚本加载并说“完成”DOMContentLoaded(它们是否相同?)并且没有更多话要说。

我没有更多关于在/ dom解析时触发的方法或事件的idéa。它必须在继续加载其他dom之前,在其他时间之前获得正确的时间标记!

没有什么可以找到的!在Living Standard — Last Updated 15 April 2019第12.2.7节的第一点之前没有什么了。结束(甚至标题与我开玩笑):在任何脚本之前应该做“交互式”的readystatechange,但它实际上没有。为什么?

对我来说,似乎readyState在大于2000个元素的本地index.html上有一个错误,因为我可以在它说“交互”之前执行延迟脚本。现在,当把那个readyState放在脚本中时我已经很清楚了(我忘了)并且它说“正在加载”,这意味着在执行时仍会加载一个大的html:

的script.js

console.log("Execute script " + document.readyState);

结论:有时延迟表现为异步,异步表现为延迟

javascript performance dom-events web-performance
1个回答
2
投票

deferthe MDN page for script elements属性的定义:

此布尔属性设置为向浏览器指示在解析文档之后但在触发DOMContentLoaded之前要执行脚本。

具有defer属性的脚本将阻止DOMContentLoaded事件触发,直到脚本加载并完成评估。

你所看到的是预期的行为。

© www.soinside.com 2019 - 2024. All rights reserved.