JavaScript 中的 Async 和 Defer 哪个更好?

大家好!希望你们一切安好。这篇文章将探讨一个有趣的 JavaScript 话题。async 和 defer 是 HTML 文档中引入外部 JavaScript 文件时使用的属性。它们影响浏览器加载和执行脚本的方式。让我们详细了解它们。

默认行为

我们通常在 HTML 页面,使用<script>标签,引用外部 JavaScript 文件。在传统方式中,通常把<script>标签,放置在 HTML 文档的<head>部分。

然而,这样做意味着在获取并执行 JavaScript 文件之前,HTML 的解析会被阻塞,导致页面加载时间变长。

如今,我们大多更倾向于把<script>标签,放在<body>标签的所有内容加载完之后,也就是</body>之前。

  1. <script src="example.js"></script>

这里是 HTML 解析和脚本执行的过程,如下图。

默认行为

原文 译文
HTML Parsing HTML 解析
HTML Parsing paused HTML 解析暂停
Script download 脚本下载
Script execution 脚本执行

Async 异步执行

当使用 async 属性,引用脚本文件时,浏览器在解析 HTML 文档的同时,异步下载脚本。脚本在后台下载,不会阻塞 HTML 解析过程。

一旦脚本下载完成,它会被异步执行,这意味着它可以在任何时候运行,甚至在 HTML 文档解析完成之前。当脚本开始执行时,如果 HTML 文档还未解析完成,此时会阻塞 HTML 解析。

  1. <script src="example.js" async></script>

如果多个脚本被设置为异步加载,它们会在下载完毕后立即执行,而不考虑它们在文档中的顺序。这在脚本不依赖于 DOM 完全加载,或其他脚本时非常有用。

Async 异步执行

Defer 异步推迟执行

当使用 defer 属性,引用脚本文件时,浏览器在解析 HTML 文档的同时,异步下载脚本。然而,脚本的执行会被推迟到 HTML 文档解析完成之后。

  1. <script src="example.js" defer></script>

带有 defer 属性的脚本,会按照它们在文档中出现的顺序执行。当脚本依赖于 DOM 完全解析后,或者脚本执行顺序很重要时,这种方式非常有用。

Defer 异步推迟执行

结论

无论是 async 还是 defer 属性,都允许在 HTML 解析过程中,异步下载脚本文件。且在下载脚本文件时,不会阻塞 HTML 解析。

两者的区别在于,脚本执行的时机:使用 async 属性,脚本会在下载完马上执行,可能会在 HTML 文档完全解析之前。而使用 defer 属性,脚本只会在 HTML 文档完全解析之后、DOMContentLoaded 事件之前执行。

需要注意的一点是,我们应当仅在脚本可以独立运行,且不依赖于 DOM 结构时使用 async,而在需要保持脚本执行顺序,或依赖于 DOM 结构时使用 defer。

希望你喜欢这篇文章,如果喜欢,不要忘记点赞哦!😃

原文:https://dev.to/fidalmathew/async-vs-defer-in-javascript-which-is-better-26gm
作者:Fidal Mathew


浏览器自动优化

据我所知,现代浏览器使用预加载扫描程序,因此它们在解析 HTML 之前就开始加载所有脚本。

不要与浏览器的预加载扫描程序冲突

(完)