Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么它将defer显示为async,将async显示为defer?获得;“dom解析事件”;正确的!但是没有?_Javascript_Performance_Dom Events_Web Performance - Fatal编程技术网

Javascript 为什么它将defer显示为async,将async显示为defer?获得;“dom解析事件”;正确的!但是没有?

Javascript 为什么它将defer显示为async,将async显示为defer?获得;“dom解析事件”;正确的!但是没有?,javascript,performance,dom-events,web-performance,Javascript,Performance,Dom Events,Web Performance,我有一个加载器,想学习异步和延迟计时。它是动态插入的外部脚本标记-无内联延迟 起初,我很难理解为什么async的行为是延迟的——它是在DOMContentLoaded之后执行的 对于2000个DOM元素,异步启动表明它可以在加载DOMContentLoaded之前执行。它从本地驱动器加载。通过从主机获取,在等待响应时异步执行脚本更有意义。这样就行了 然后我改为测试延时和超调。。现在我要和一个笑话抗争,为什么延迟在加载DOMContentLoaded之前表现为异步执行 由于100000个DOM元素

我有一个加载器,想学习异步和延迟计时。它是动态插入的外部脚本标记-无内联延迟

起初,我很难理解为什么async的行为是延迟的——它是在DOMContentLoaded之后执行的

对于2000个DOM元素,异步启动表明它可以在加载DOMContentLoaded之前执行。它从本地驱动器加载。通过从主机获取,在等待响应时异步执行脚本更有意义。这样就行了

然后我改为测试延时和超调。。现在我要和一个笑话抗争,为什么延迟在加载DOMContentLoaded之前表现为异步执行

由于100000个DOM元素占用了30多秒的时间,脚本的执行仍然发生在加载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");
console.log("Execute script");
script.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");
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>
在DOM准备好使用之前,决不应执行延迟脚本
现在我们有一个例子,DOMContentLoaded在DOM出现在屏幕上之前激发。怎么做


编辑#1

当心DOMContentLoaded-我想要“解析dom内容”
(这就是代码中的bug——或者在我的脑海中)
更正(感谢尖头)-用我的话说

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

所以我需要的是某种“解析的DOMContent”。我发现最好的是readystatechange事件和文档。readyState

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

s.onload = function(){ console.log(document.readyState) }
在Chrome和Firefox控制台中显示足够的dom:

Fetch script
Execute script
loading
DOMContentLoaded
这意味着一个延迟脚本在运行时执行! 是-正在加载,直到加载DOMContentLoaded。遗憾的是readyState没有告诉dom何时被解析!我也试过

document.addEventListener('readystatechange', function() {
  console.log(">>" + document.readyState); 
});
这不会在“加载”时触发,因为它已经触发了,但在延迟加载脚本后会显示“交互式”,并在加载DOMContentLoaded的位置显示“完成”(它们是相同的吗?),并且没有更多的内容要说

我不再有在解析dom时触发的方法或事件的idéa。必须在继续加载其他dom内容之前,才能在其他计时之前获得正确的计时标记

再也找不到了!在第12.2.7节结尾的第一点之前没有其他内容(甚至是与我开玩笑的标题):readystatechange应该在任何脚本之前进行“交互式”,但实际上并没有。为什么?

对我来说,readyState在大于2000个元素的local index.html上似乎有一个bug,因为我可以在它说“interactive”之前执行一个延迟脚本。现在,将readyState也放在脚本中(我忘了)时已经很清楚了,它说的是“加载”,这意味着在执行时仍在加载一个大的html:

script.js

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

结论:有时延迟行为为异步,异步行为为延迟

延迟属性的定义如下:

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

带有defer属性的脚本将阻止触发DOMContentLoaded事件,直到脚本加载并完成计算


您看到的是预期的行为。

谢谢您的快速回答!是否存在“文档已被解析”事件?由于
defer
的工作方式,脚本实际上正在有效运行这一事实意味着文档已被解析。您可以通过使用
defer
创建脚本来验证这一点,并让它检查您放置在
末尾的具有某个id的元素。如果脚本使用
.getElementById()
找到该元素,则知道该文档已被解析。“interactive”有一个早期事件,但在“Execute script”之前都没有执行:document.addEventListener('readystatechange',function(){console.log(document.readyState);});有了足够的html。。。在控制台中,我看到“执行脚本”和下一行的“加载”,这意味着Chrome run s.defer=true;s、 异步=假;尽管DOM正在加载!!!在两台计算机上测试。延迟在Chrome中是异步的,但在FF中不是