>[danger]Js中async和defer的区别 在HTML文档中,`<script>`标签用于引入JavaScript脚本。默认情况下,浏览器在解析HTML时遇到`<script>`标签会执行以下操作: 1. **阻塞HTML解析**:浏览器会暂停解析HTML文档,直到脚本下载并执行完成。这是因为早期的JavaScript脚本可能会修改DOM。 2. **下载脚本**:浏览器发起网络请求下载脚本文件。 3. **执行脚本**:下载完成后,浏览器执行脚本。如果脚本是外部的(即`src`属性指定了一个URL),则执行前会先解析并构建该脚本的DOM。 4. **继续HTML解析**:脚本执行完成后,浏览器继续解析HTML文档。 然而,这种阻塞行为可以通过`<script>`标签的属性来改变: - **`async`属性**:当`<script>`标签包含`async`属性时,脚本会异步下载,不会阻塞HTML解析。下载完成后,脚本会立即执行,但仍然可能阻塞后续的脚本执行。 - **`defer`属性**:当`<script>`标签包含`defer`属性时,脚本会异步下载,不会阻塞HTML解析。与`async`不同,`defer`脚本会等到文档解析完成后,按照它们在文档中出现的顺序执行。 以下是`<script>`标签不同属性对加载和执行行为的影响的表格: | 属性 | 下载 | HTML解析 | 执行时机 | 执行顺序 | |------|------|----------|----------|----------| | 无 | 同步 | 阻塞 | 下载后 | 未知 | | async | 异步 | 不阻塞 | 下载后 | 未知 | | defer | 异步 | 不阻塞 | 解析后 | 文档顺序 | **示例**: ```html <!-- 阻塞加载,执行时机未知,可能在解析DOM时阻塞 --> <script src="script1.js"></script> <!-- 异步加载,不阻塞HTML解析,执行时机在下载完成后,可能在文档解析之前或之后 --> <script async src="script2.js"></script> <!-- 异步加载,不阻塞HTML解析,执行时机在文档解析完成后,按照在文档中出现的顺序 --> <script defer src="script3.js"></script> ``` **最佳实践**: - 如果脚本不依赖于DOM,可以使用`async`属性来避免阻塞。 - 如果脚本之间有依赖关系,或者需要在DOM完全解析后执行,使用`defer`属性。 - 对于内联脚本(即直接在`<script>`标签中编写JavaScript代码),通常不需要`async`或`defer`属性,除非脚本非常短,且不依赖于页面其他部分的执行。 通过合理使用这些属性,可以提高页面的加载性能和响应速度。