返回
用图解的方式理解<script>标签的defer/async与DOMContentLoaded/Load的区别
前端
2024-02-18 12:56:54
了解 <script>
标签的性能优化
随着 Web 技术的不断发展,页面加载速度和交互性变得至关重要。<script>
标签对于加载外部脚本文件,从而为网页增添功能非常重要。然而,脚本加载方式可能会对页面性能产生负面影响。
<script>
标签的默认行为
当浏览器遇到 <script>
标签时,它会立即暂停解析 HTML,然后执行脚本。这可能会导致页面上其他元素的加载和交互被阻塞。
defer 和 async 属性
为了解决这个问题,HTML5 引入了 defer
和 async
属性,它们可以改变 <script>
标签的执行顺序,从而避免阻塞页面渲染。
- defer: 使用
defer
属性,脚本将在 HTML 解析完成后执行,但在页面渲染之前。这确保了脚本不会阻塞页面渲染,但它可能会阻止页面上其他元素的交互。 - async: 使用
async
属性,脚本将在 HTML 解析期间执行,但它不会阻塞页面渲染或其他元素的交互。这意味着脚本可以并行执行,从而提高页面的加载速度和交互性。
DOMContentLoaded 和 Load 事件
在讨论脚本加载时,了解 DOMContentLoaded 和 Load 事件也很重要。
- DOMContentLoaded: DOMContentLoaded 事件会在 DOM 解析完成后触发。这意味着 HTML 已被解析,但外部资源(如图像、样式表和脚本)可能尚未加载完成。
- Load: Load 事件会在所有资源(包括外部资源)加载完成后触发。这意味着此时页面上的所有元素都已加载完成,页面可以正常交互。
图解<script>
标签的执行顺序
[图片]
上图显示了 <script>
标签的 defer
和 async
属性与 DOMContentLoaded 和 Load 事件之间的关系。
使用建议
- 使用 defer: 当你希望在页面渲染前执行脚本,但不希望它阻塞页面渲染时,可以使用
defer
属性。例如,当你希望在页面加载后立即执行一个分析脚本时。 - 使用 async: 当你希望在 HTML 解析期间执行脚本,且不希望它阻塞页面渲染或其他元素的交互时,可以使用
async
属性。例如,当你希望在页面加载后立即加载一个广告脚本时。
注意事项
defer
和async
属性不能同时使用。如果同时使用,则以async
属性为准。defer
和async
属性只对外部脚本有效。如果脚本是内联的,则这两个属性不起作用。defer
和async
属性不保证脚本执行的顺序。脚本的执行顺序可能受脚本的位置、浏览器类型和其他因素的影响。
结论
理解 <script>
标签的 defer
和 async
属性以及 DOMContentLoaded 和 Load 事件对于编写高效的 Web 代码至关重要。通过优化脚本加载顺序,你可以提高页面的加载速度和交互性,从而提升用户体验。
常见问题解答
-
什么时候应该使用
defer
属性?- 当需要在页面渲染前执行脚本,但又不希望它阻塞页面渲染时。
-
什么时候应该使用
async
属性?- 当需要在 HTML 解析期间执行脚本,且不希望它阻塞页面渲染或其他元素的交互时。
-
defer
和async
属性有什么区别?defer
属性确保脚本在 HTML 解析完成后执行,但在页面渲染之前执行。async
属性确保脚本在 HTML 解析期间执行,并且不会阻塞页面渲染或其他元素的交互。
-
如何同时使用
defer
和async
属性?- 这是不允许的。如果同时使用,则以
async
属性为准。
- 这是不允许的。如果同时使用,则以
-
defer
和async
属性适用于哪些类型的脚本?- 它们只适用于外部脚本。如果脚本是内联的,则这两个属性不起作用。