【问题标题】:Execution order of dynamically added script tags marked with defer attribute?标有 defer 属性的动态添加的脚本标签的执行顺序?
【发布时间】:2021-10-18 01:11:29
【问题描述】:

我有一些动态创建小部件的应用程序。一些小部件需要包含一些库(例如 Codemirror、Tinymce、jQuery 等)。这些脚本在第一次创建小部件时动态添加到文档中,否则根本不包含它们(如果不在每个请求中使用它们,就预先包含所有可能的小部件脚本会浪费资源)。

可以在服务器端或客户端创建小部件。在客户端,脚本被动态添加到页面上,否则服务器在生成的 html 输出中作为脚本标签添加。

如果在客户端,我注意到执行顺序没有得到遵守。例如,一些 Codemirror 插件首先加载(因为更轻量级)但它们失败了,因为主库尚未加载(即使它作为脚本标签出现在它们之前)。

我尝试使用defer 属性,根据MDN 尊重其出现的执行顺序,即使脚本是异步加载的。然而我注意到它失败了(注意我只使用defer 属性而不是async)。目前已在 Firefox 和 Chrome 上测试。

动态添加的脚本标签也是这样吗?

如果不是,为了尊重执行顺序,还有什么替代方法(不使用 onload 回调)?

谢谢!

【问题讨论】:

  • 这能回答你的问题吗? Load ordering of dynamically added script tags
  • 不,我正在寻找一种最新的解决方案(2021 年),最好不要求助于回调,因为脚本超出了我的控制范围。类似于 defer 属性的东西,但用于动态脚本标签
  • "不使用 onload 回调" - 我认为不可能实现。
  • @NikosM。 2021 年的解决方案是使用在 import 语句中声明其依赖关系的模块,但我怀疑您的小部件和插件不支持这一点(即您希望在全局范围内将它们作为脚本执行)
  • @Bergi 这些脚本不一定是模块。如果使用回调是唯一的解决方案(有人可以通过一些参考来证明这一点),那么就是这样。我可以接受这样合理的回答

标签: javascript deferred-execution


【解决方案1】:

我解决了这个问题,方法是使用回调等到脚本加载完毕后再在 DOM 上附加新脚本(这取决于之前的脚本)。

但是我希望这个过程由浏览器处理(例如使用defer 属性)。

如果有人有一个解决方案,其中浏览器为动态添加的脚本标签处理所有这些互连,请随时发布答案。

【讨论】:

  • 我认为浏览器不会这样做。这就是为什么 AMD(异步模块定义)和像 require.js 这样的加载器库被发明出来的原因——它们允许你一次加载所有模块,然后以正确的顺序执行它们。从那时起,ES6 模块被引入作为浏览器处理此问题的本机解决方案。
  • 我能说什么,寄予厚望:) 消除样板代码
猜你喜欢
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 2013-09-05
  • 2022-11-23
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 2018-02-22
相关资源
最近更新 更多