gpt4 book ai didi

javascript - 为什么它显示延迟为异步和异步为延迟?正确理解 "dom parsed event"!但有没有?

转载 作者:行者123 更新时间:2023-12-02 23:47:37 24 4
gpt4 key购买 nike

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

起初,我很难理解为什么异步会表现得像延迟 - 它在 DOMContentLoaded 之后执行

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

然后我改为测试 defer 和 surprice。现在我与为什么 defer 表现为异步 - 在 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");

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 准备好使用之前,决不应该执行延迟脚本
现在我们遇到这样的情况:DOMContentLoaded 在 DOM 在屏幕上显示之前触发。怎么办?

<小时/>

编辑 #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 不告诉 dom 何时被解析!我也试过了..

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

这不会在“加载”时触发,因为它已经触发了,但它在延迟脚本加载后说“交互式”,并在 DOMContentLoaded 所在的位置说“完成”(它们相同吗?)并且没有更多可说的。

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

没有更多可找到的了! Living Standard — Last Updated 15 April 2019 中的第一点之前没有其他内容了第 12.2.7 节结束(甚至标题跟我开玩笑):readystatechange 应该在任何脚本之前进行“交互”,但实际上并没有。为什么?

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

脚本.js

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

结论:有时 defer 表现得像异步,异步表现得像 defer

最佳答案

the MDN page for script elements 上的 defer 属性的定义:

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.

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

关于javascript - 为什么它显示延迟为异步和异步为延迟?正确理解 "dom parsed event"!但有没有?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55783364/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com