defer 特性告诉浏览器不要等待脚本。相反,浏览器将继续处理 HTML,构建 DOM。脚本会“在后台”下载,然后等 DOM 构建完成后,脚本才会执行。
换句话说:
具有 defer 特性的脚本不会阻塞页面。
具有 defer 特性的脚本总是要等到 DOM 解析完毕,但在 DOMContentLoaded 事件之前执行。
页面内容立即显示。
DOMContentLoaded 事件处理程序等待具有 defer 特性的脚本执行完成。它仅在脚本下载且执行结束后才会被触发。
defer 特性除了告诉浏览器“不要阻塞页面”之外,还可以确保脚本执行的相对顺序。因此,即使 small.js 先加载完成,它也需要等到 long.js 执行结束才会被执行。
当我们需要先加载 JavaScript 库,然后再加载依赖于它的脚本时,这可能会很有用。
如果 <script> 脚本没有 src,则会忽略 defer 特性。
async 特性意味着脚本是完全独立的:
浏览器不会因 async 脚本而阻塞(与 defer 类似)。
其他脚本不会等待 async 脚本加载完成,同样,async 脚本也不会等待其他脚本。
DOMContentLoaded
和异步脚本不会彼此等待:
DOMContentLoaded 可能会发生在异步脚本之前(如果异步脚本在页面完成后才加载完成)