请说说`<script>`、`<script async>`和`<script defer>`的区别

在前端开发中,<script><script async><script defer> 都用于在 HTML 文档中嵌入 JavaScript 代码,但它们在加载和执行脚本的方式上有所不同,从而影响页面的渲染性能和行为。

1. <script> (默认行为):

  • 加载和执行: 浏览器解析到 <script> 标签时,会立即停止解析 HTML,下载脚本文件,然后执行脚本。执行完毕后,浏览器才会继续解析剩余的 HTML。
  • 阻塞: 这是阻塞式的加载方式,意味着在脚本下载和执行完成之前,页面渲染会被阻塞。如果脚本文件很大或网络速度慢,会导致页面出现明显的延迟,用户体验不佳。
  • 顺序执行: 脚本会按照它们在 HTML 中出现的顺序依次下载和执行。

2. <script async>:

  • 加载和执行: 浏览器解析到 <script async> 标签时,会异步下载脚本文件,不会阻塞 HTML 解析。脚本下载完成后,浏览器会立即暂停 HTML 解析并执行脚本,执行完毕后再继续解析 HTML。
  • 非阻塞: 异步加载,不会阻塞页面渲染。
  • 执行顺序不确定: 多个带有 async 属性的脚本的执行顺序是不确定的,它们可能会以任何顺序执行,取决于哪个脚本先下载完成。因此,async 适用于不依赖于其他脚本或不影响页面结构的独立脚本,例如统计分析脚本。

3. <script defer>:

  • 加载和执行: 浏览器解析到 <script defer> 标签时,会异步下载脚本文件,不会阻塞 HTML 解析。脚本下载完成后,会等待 HTML 解析完成,并在 DOMContentLoaded 事件触发之前执行。
  • 非阻塞: 异步加载,不会阻塞页面渲染。
  • 顺序执行: 带有 defer 属性的脚本会按照它们在 HTML 中出现的顺序执行。这对于需要操作 DOM 或依赖其他脚本的脚本非常有用。

总结:

特性 <script> <script async> <script defer>
加载方式 同步 异步 异步
阻塞 HTML 解析
执行时机 立即 下载完成后立即执行 HTML 解析完成后,DOMContentLoaded 事件触发前
执行顺序 按顺序 不确定 按顺序
适用场景 需要立即执行的脚本,但会阻塞页面渲染 独立脚本,例如统计分析脚本 需要操作 DOM 或依赖其他脚本的脚本,例如初始化代码

示例:

<!DOCTYPE html>
<html>
<head>
  <title>Script Example</title>
</head>
<body>
  <script src="script1.js"></script>  <!-- 默认,阻塞 -->
  <script async src="script2.js"></script> <!-- 异步,执行顺序不确定 -->
  <script defer src="script3.js"></script> <!-- 异步,按顺序执行 -->
</body>
</html>

选择哪种方式取决于脚本的功能和它们之间的依赖关系。如果脚本之间没有依赖关系且不影响页面渲染,可以使用 async。如果脚本需要操作 DOM 或依赖其他脚本,最好使用 defer。 尽量避免使用默认的 <script> 方式,除非脚本必须立即执行并且可以接受阻塞页面渲染。

posted @ 2024-11-21 12:35  王铁柱6  阅读(19)  评论(0编辑  收藏  举报