返回

用图解的方式理解<script>标签的defer/async与DOMContentLoaded/Load的区别

前端

了解 <script> 标签的性能优化

随着 Web 技术的不断发展,页面加载速度和交互性变得至关重要。<script> 标签对于加载外部脚本文件,从而为网页增添功能非常重要。然而,脚本加载方式可能会对页面性能产生负面影响。

<script> 标签的默认行为

当浏览器遇到 <script> 标签时,它会立即暂停解析 HTML,然后执行脚本。这可能会导致页面上其他元素的加载和交互被阻塞。

defer 和 async 属性

为了解决这个问题,HTML5 引入了 deferasync 属性,它们可以改变 <script> 标签的执行顺序,从而避免阻塞页面渲染。

  • defer: 使用 defer 属性,脚本将在 HTML 解析完成后执行,但在页面渲染之前。这确保了脚本不会阻塞页面渲染,但它可能会阻止页面上其他元素的交互。
  • async: 使用 async 属性,脚本将在 HTML 解析期间执行,但它不会阻塞页面渲染或其他元素的交互。这意味着脚本可以并行执行,从而提高页面的加载速度和交互性。

DOMContentLoaded 和 Load 事件

在讨论脚本加载时,了解 DOMContentLoaded 和 Load 事件也很重要。

  • DOMContentLoaded: DOMContentLoaded 事件会在 DOM 解析完成后触发。这意味着 HTML 已被解析,但外部资源(如图像、样式表和脚本)可能尚未加载完成。
  • Load: Load 事件会在所有资源(包括外部资源)加载完成后触发。这意味着此时页面上的所有元素都已加载完成,页面可以正常交互。

图解<script> 标签的执行顺序

[图片]

上图显示了 <script> 标签的 deferasync 属性与 DOMContentLoaded 和 Load 事件之间的关系。

使用建议

  • 使用 defer: 当你希望在页面渲染前执行脚本,但不希望它阻塞页面渲染时,可以使用 defer 属性。例如,当你希望在页面加载后立即执行一个分析脚本时。
  • 使用 async: 当你希望在 HTML 解析期间执行脚本,且不希望它阻塞页面渲染或其他元素的交互时,可以使用 async 属性。例如,当你希望在页面加载后立即加载一个广告脚本时。

注意事项

  • deferasync 属性不能同时使用。如果同时使用,则以 async 属性为准。
  • deferasync 属性只对外部脚本有效。如果脚本是内联的,则这两个属性不起作用。
  • deferasync 属性不保证脚本执行的顺序。脚本的执行顺序可能受脚本的位置、浏览器类型和其他因素的影响。

结论

理解 <script> 标签的 deferasync 属性以及 DOMContentLoaded 和 Load 事件对于编写高效的 Web 代码至关重要。通过优化脚本加载顺序,你可以提高页面的加载速度和交互性,从而提升用户体验。

常见问题解答

  1. 什么时候应该使用 defer 属性?

    • 当需要在页面渲染前执行脚本,但又不希望它阻塞页面渲染时。
  2. 什么时候应该使用 async 属性?

    • 当需要在 HTML 解析期间执行脚本,且不希望它阻塞页面渲染或其他元素的交互时。
  3. deferasync 属性有什么区别?

    • defer 属性确保脚本在 HTML 解析完成后执行,但在页面渲染之前执行。async 属性确保脚本在 HTML 解析期间执行,并且不会阻塞页面渲染或其他元素的交互。
  4. 如何同时使用 deferasync 属性?

    • 这是不允许的。如果同时使用,则以 async 属性为准。
  5. deferasync 属性适用于哪些类型的脚本?

    • 它们只适用于外部脚本。如果脚本是内联的,则这两个属性不起作用。