我
请解释 `<script>`、`<script async>` 和 `<script defer>` 的区别
难度:
<script>
、<script async>
和 <script defer>
都是用于在 HTML 文档中引入和执行 JavaScript 脚本的标签,但它们在加载和执行脚本时的行为有所不同:
<script>
:当浏览器遇到一个没有async
或defer
属性的<script>
标签时,它会立即下载并执行脚本。在此期间,浏览器会阻塞 HTML 文档的解析。这意味着,如果脚本文件很大或者下载速度较慢,用户可能会看到一个空白的页面,直到脚本加载并执行完成。这种方式适用于那些需要在页面解析过程中立即执行的脚本,例如修改或操作 DOM 的脚本。<script async>
:当浏览器遇到一个带有async
属性的<script>
标签时,它会异步地下载脚本,同时继续解析 HTML 文档。一旦脚本下载完成,浏览器会暂停 HTML 文档的解析,执行该脚本,然后恢复解析。这意味着,脚本的加载和执行不会阻塞页面的渲染,但它们的执行顺序是不确定的。async
属性适用于那些不依赖其他脚本且不需要在特定时间执行的脚本,例如分析和度量脚本。<script defer>
:当浏览器遇到一个带有defer
属性的<script>
标签时,它会异步地下载脚本,同时继续解析 HTML 文档。与async
不同的是,带有defer
属性的脚本会在文档解析完成后(即在DOMContentLoaded
事件触发前)按照它们在文档中出现的顺序执行。这意味着,这些脚本的加载不会阻塞页面渲染,同时它们的执行顺序是确定的。defer
属性适用于那些依赖于 DOM 结构或者其他脚本的脚本。
总结:
<script>
:同步加载并执行脚本,阻塞 HTML 文档解析。<script async>
:异步加载脚本,不阻塞 HTML 文档解析,执行顺序不确定。<script defer>
:异步加载脚本,不阻塞 HTML 文档解析,按照文档顺序执行,通常在DOMContentLoaded
事件前执行。