在我的 polyfill 和其他脚本上设置 defer 会保证它们按顺序加载吗?

Will setting defer on my polyfill and other scripts guarantee that they're loaded in order?

我正在使用 polyfill.io 为老客户填充 Promise 和 fetch。在 their website 他们建议使用脚本加载器或他们的回调来确保脚本在 运行 现代代码之前完全加载:

We recommend the use of the async and defer attributes on tags that load from the polyfill service, but loading from us in a non-blocking way means you can't know for certain whether your own code will execute before or after the polyfills are done loading.

To make sure the polyfills are present before you try to run your own code, you can attach an onload handler to the https://cdn.polyfill.io script tag, use a more sophisticated script loader or simply use our callback argument to evaluate a global callback when the polyfills are loaded:

但是,在两个脚本上设置 defer 不应该已经保证它们是异步加载的,但仍然按照它们在文档中出现的顺序加载(除非浏览器不支持延迟)?

<script src="https://cdn.polyfill.io/v2/polyfill.min.js" defer></script>
<script src="modernscript.js" defer></script>

根据 MDN documentation defer 属性仅定义页面加载时间点,此时将发生脚本加载。

从您引用的文档中可以看出:

To make sure the polyfills are present before you try to run your own code, you can attach an onload handler to the https://cdn.polyfill.io script tag

因为(正如对此答案的评论所指出的)无法清楚地看到是否将执行 defer 脚本(1, 2)并且考虑到可能的浏览器实现差异 - 它可能依赖这种行为并不是最好的主意。

所以更好的方法是:

  1. 使用一些脚本加载器(例如RequireJS
  2. 将提议的 onload 处理程序添加到第一个 <script> 标记并创建动态 <script> 标记以将您的代码加载到此处理程序中
  3. 将您的代码与 Promise polyfill 捆绑在一起(手动或使用 webpack 之类的捆绑器)并作为单个捆绑包加载。

更新: 正如 @PeterHerdenborg 在 中指出的那样 - MDN 文档现在明确指出:

Scripts with the defer attribute will execute in the order in which they appear in the document.