Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/436.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 如何从CDN异步加载多个文件(但同步执行)?_Javascript_Html_Dom_Loading - Fatal编程技术网

Javascript 如何从CDN异步加载多个文件(但同步执行)?

Javascript 如何从CDN异步加载多个文件(但同步执行)?,javascript,html,dom,loading,Javascript,Html,Dom,Loading,当下载多个常用的javascript/css文件(例如boostrap和jquery)时,许多主题(如)建议使用CDN,其中一个主要参数可以用于异步加载它们 这是怎么回事?据我所知,头文件中的标签是同步读取的,因此在第一个CDN文件完成之前,它实际上不会查看第二个CDN文件 <script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <

当下载多个常用的javascript/css文件(例如boostrap和jquery)时,许多主题(如)建议使用CDN,其中一个主要参数可以用于异步加载它们

这是怎么回事?据我所知,头文件中的标签是同步读取的,因此在第一个CDN文件完成之前,它实际上不会查看第二个CDN文件

  <script src="//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
  <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>

只需添加
延迟

我认为您仍然可以使用
延迟
,只需将回退代码放入事件处理程序中即可

延迟

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

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

[……]

具有defer属性的脚本将按以下顺序执行: 它们出现在文档中

。。。所以这可能是个不错的选择

或者,您也可以将回退代码放在一个单独的
.js
文件中,然后也可以使用
defer
加载回退代码,这取决于引号的底部,因此顺序执行。

与其说是异步,不如说是并行。(它们当然是相关的,但与限制从同一来源多次下载相关的CDN论点是关于并行性的。)

如何使页面异步下载脚本,但同步执行脚本

任何一个好的浏览器,当你看到三个脚本标签时,都会并行下载它们(从同一个站点下载到它的并行限制),然后按顺序执行它们。你不必做任何事情来实现这一点。浏览器在HTML中预读以查找要获取的资源

使用
document.write添加回退脚本可能会使浏览器执行此操作的能力复杂化,甚至会阻止它,但您可以使用
()以声明方式确保它。将其与故障CDN资源的回退脚本相结合,可能会出现如下情况:


如果(!/*加载条件*/)文档。写入(/*回退*/);
如果(!/*加载条件*/)文档。写入(/*回退*/);
如果(!/*加载条件*/)文档。写入(/*回退*/);
请注意,这不会预加载回退。可以,但即使CDN工作时也会加载它们,这会浪费最终用户的带宽。回退可能是针对CDN不可用的临时降级情况,在这种情况下,降级的用户体验可能还可以。(你甚至可以在安排后备计划时向用户显示问题的指标,比如Gmail的“某物花费的时间比平时长”指标。)


如果您对重复URL感到烦恼,并且您对
文档没有意见。请少量编写
(就像您看起来的那样),您可以通过以下方式避免重复URL:


变量脚本=[
{
url://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js,
好的:函数(){return/*检查它是否已加载*/;}
},
{
url://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js”,
好的:函数(){return/*检查它是否已加载*/;}
},
{
url://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js”,
好的:函数(){return/*检查它是否已加载*/;}
},
];
scripts.forEach(函数(脚本){
文件。写(“”);
});
scripts.forEach(函数(脚本、索引){
var fallback=script.url.substring(script.url.lastIndexOf('/')+1);
文件。写(“”);
document.write('if(!scripts['+index+'].ok())document.write(\'\'');');
});

(由于这些都是内联脚本,您不太可能传输,因此我将语法保持在ES5级别,以防您必须支持过时的环境。)

谢谢!在.js文件中编写回退代码听起来是一个非常干净和不错的解决方法,但是该文件应该是什么样子呢?因为我不认为
document.write()
在这一点上仍然合适。在发明任何东西之前,我实际上会尝试一下。如果
document.write()
到目前为止仍然有效(这里我假设您已经通过故意提供非工作链接或类似的方式对其进行了测试),我不确定为什么它现在不能工作。不,如果其中一个脚本出现故障,您不能使用“延迟”并保留脚本的顺序。如果加载A、B和C,A失败,B和C将运行。失败的
defer
脚本不会永远阻止
DOMContentLoaded
。Re
document.write
:您不能使用
document.write
来处理
延迟
'd脚本失败。(你根本不能在错误处理程序中使用它,它会清除页面内容。)CC@user1111929在Chrome控制台中注意到这个警告:
解析器阻塞、跨站点(即不同的eTLD+1)脚本,https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js,通过document.write调用。由于网络连接不良,浏览器可能会在本次或将来的页面加载中阻止对此脚本的网络请求。如果在此页面加载中被阻止,将在后续控制台消息中确认。看见https://www.chromestatus.com/feature/5718547946799104 有关更多详细信息。
我认为这还不算太糟,因为他们仍然有本地回退,但我可以以某种方式隐藏警告吗?此外,这种方法与来自的方法相比如何,即类似于
的方法?
  <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>
<script>    $.fn.modal || document.write('<script src="Script/bootstrap.min.js">\x3C/script>')</script>