Javascript 为什么它将defer显示为async,将async显示为defer?获得;“dom解析事件”;正确的!但是没有?
我有一个加载器,想学习异步和延迟计时。它是动态插入的外部脚本标记-无内联延迟 起初,我很难理解为什么async的行为是延迟的——它是在DOMContentLoaded之后执行的 对于2000个DOM元素,异步启动表明它可以在加载DOMContentLoaded之前执行。它从本地驱动器加载。通过从主机获取,在等待响应时异步执行脚本更有意义。这样就行了 然后我改为测试延时和超调。。现在我要和一个笑话抗争,为什么延迟在加载DOMContentLoaded之前表现为异步执行 由于100000个DOM元素占用了30多秒的时间,脚本的执行仍然发生在加载DOMContentLoaded之前。怎么了 这是我测试的相关部件 loader.jsJavascript 为什么它将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元素
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中不是