gpt4 book ai didi

javascript - `document.write` 和 DOM API 在阻止后续请求方面没有区别 - 为什么?

转载 作者:行者123 更新时间:2023-11-30 12:02:54 26 4
gpt4 key购买 nike

我正在阅读 this article关于 document.write ,它指出:

Sometimes the scripts are added by the document.write. Don’t use this method, as the rest of the page will await for script loading and execution.

If the remote server hands up, the page will may take too much to load.

我不太明白使用 document.write 之间的区别和 DOM API 在阻塞方面。我在 Chrome 中使用以下 <head> 运行了一个简单的实验 block :

1) 使用 document.write :

<head>
<script src="index-1.js"></script>
<script>
var url = 'index-2.js'
document.write('<script src="'+url+'"></scr'+'ipt>');
</script>
<link rel="stylesheet" href="index.css">
</head>

2) 使用 DOM API :

<head>
<script src="index-1.js"></script>
<script>
var script = document.createElement('script');
script.src = 'index-2.js';
document.documentElement.firstChild.appendChild(script);
</script>
<link rel="stylesheet" href="index.css">
</head>

在这两种情况下,Chrome 都会等待脚本 index-1.js在加载前执行 index-2.js .这是图片:

enter image description here

所以我很困惑。我做错了或理解错了吗?

编辑:

如果我在链接标签后添加第三个脚本标签

<link rel="stylesheet" href="index.css">
<script src="index-3.js"></script>

然后我得到以下结果:

enter image description here

最佳答案

在第一个代码示例中,浏览器等待index-2.js。在运行任何进一步的脚本之前和显示您的页面之前加载和执行。据说这是一个"blocking"加载。在加载脚本之前,它会阻止解析器的进一步处理。

在第二个代码示例中(插入了 .appendChild() 的脚本),浏览器不会等待 index-2.js。在继续其他脚本或显示您的页面之前加载或运行。这里index-2.js异步加载,同时继续处理页面中的其他内容。据说这是一个"non-blocking"加载。它不会在加载时阻止浏览器的进一步进展。一旦它在后台加载完动态脚本,浏览器就可以随时执行它(可能是在它目前无事可做的时候)。当它实际执行时,它会因浏览器而异,并且不受规范约束。

因此,时间与index-1.js无关.那是一个同步脚本标签。它在两个例子中都是阻塞的。浏览器不会处理过去的 <script>标签。

区别在于插入 index-2.js 后会发生什么.

执行顺序是由规范定义的,因此您必须关注或衡量它。这取决于浏览器何时真正决定通过网络加载脚本,因此您不能使用加载条形图来查看执行情况。显然,它不能在解析器知道脚本之前开始加载它,它必须在需要执行它之前加载它,但在此期间,浏览器可以使用自己的逻辑来决定何时加载它。由于每个浏览器对其尝试从一台主机下载的同时资源的数量有限制,因此它决定下载脚本的确切时间很容易因浏览器而异。

并且,请记住,使用 .appendChild() 插入的非阻塞脚本可以在浏览器需要的任何时间运行。它几乎可以立即运行(如果浏览器在其缓存中有该脚本并且因为它正在等待其他资源而无事可做)或者它可以在整个加载过程快结束时运行它。当您使用 .appendChild() 插入它时,您是在指示浏览器不要阻止当前页面的解析和加载来运行此脚本,但是只要浏览器具有该脚本的内容,它就可以随时运行它。

当您使用 document.write() 插入它时,您指示浏览器在当前脚本标记运行完毕后立即运行它,这显然意味着它也必须立即加载。


如果你把这个:

<script src="index-3.js"></script>

就在<link>之前标签,那么你的时间轴就会像你看到的那样讲述整个故事 index-3.js在第二个代码示例中运行得更快,因为它不会等待 index-2.js加载并运行。事实上,如果你把 console.log()每个 index-1.js 中的条目, index-2.jsindex-3.js , 然后你可以看到执行顺序的不同。


仅供引用,您还可以使用 asyncdefer <script> 中的属性用于制作内联的标签 <script>标签是非阻塞的。更多关于这些选项的讨论:load and execute order of scripts .

关于javascript - `document.write` 和 DOM API 在阻止后续请求方面没有区别 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36195762/

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