[JS基础]关于script标签的defer和async属性的疑惑

最近回过头重看红宝书,看到script标签的时候有一个疑惑:
在html文件中,给script标签加上defer或者async属性后,如果JS文件异步下载还未结束的时候文档就解析完成了会怎么样?是等待JS下载完成、解析并且执行完成后再触发DOMContantLoaded方法吗?
希望大家帮我解惑,谢谢:)

阅读 2.6k
1 个回答
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 execute in the order in which they appear in the document.
此属性对内联的JS脚本无效。
script的defer值的设置就是告诉浏览器,这个脚本将在DOM文件解析完成后DOMContentLoaded事件发生之前执行。有defer属性的script脚本按在HTML文件中出现的顺序顺序执行。

async HTML5
This is a Boolean attribute indicating that the browser should, if possible, execute the script asynchronously.
Dynamically inserted scripts execute asynchronously by default, so to turn on synchronous execution (i.e. scripts execute in the order they were inserted) set async=false.
此属性对内联的JS脚本无效
设置async属性就是告诉浏览器如果有可能就异步执行指定的JS脚本,动态插入的脚本默认是异步加载执行的,除非手动设置async=false

defer 延迟执行,但会在DOMContentLoaded事件发生之前执行完毕,defer脚本会顺序同步的执行。defer延迟是相对于整个文档的解析来讲,指的脚本的开始加载的时间点。

async 异步执行,具体什么时间点执行由浏览器决定,具体的时间点不确定,但是确定会去加载执行,设置了async的各个脚本加载执行完毕的时间和它们放置插入的顺序没有确定的关系。和DOMContentLoaded事件发生也没有确定的前后关系,可能在DOMContentLoaded事件前某个async脚本执行完了,也有可能async脚本一个都没有执行。async指的是文档的加载方式,同步的还是异步的,并不指定什么时候开始加载。一般都会处理成在DOMContentLoaded事件发生后,就相当于这些脚本是通过JS脚本动态添加的

normal.js

console.log("normal loaded js");

defer.js

console.log("defer loaded js");

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <script type="text/javascript" defer src="../js/defer.js"></script>
    <script type="text/javascript" src="../js/normal.js"></script>
    <title>Defer Script</title>
    <script>
        document.addEventListener("DOMContentLoaded", function(event) {
            console.log("DOMContentLoaded");
        });
    </script>
</head>
<body>

</body>
</html>

输出

normal loaded js
defer loaded js
DOMContentLoaded
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题