XuLaLa.Tech

首页客户端下载Windows 使用V2Ray 教程SSR 教程Clash 教程

Web性能优化之async和defer

2025.04.09
在Web开发中,页面加载速度和性能是用户体验的关键因素之一。JavaScript脚本在Web页面中的加载和执行方式会显著影响页面的渲染速度和交互性能。为了优化页面加载性能,HTML5引入了两个重要的属性——asyncdefer,用于控制外部JavaScript文件的加载和执行顺序。

文章目录

  • 1 一、JavaScript加载和执行的基本原理
    • 1.1 浏览器解析过程中的阻塞
  • 2 二、async属性
    • 2.1 async的工作机制
    • 2.2 适用场景
    • 2.3 async的优点和缺点
  • 3 三、defer属性
    • 3.1 defer的工作机制
    • 3.2 适用场景
    • 3.3 defer的优点和缺点
  • 4 四、async与defer的比较
    • 4.1 示例
  • 5 五、适用建议

一、JavaScript加载和执行的基本原理

在HTML中,当浏览器遇到一个<script>标签时,默认行为是立即停止解析HTML,开始下载并执行该脚本。这个过程会阻塞HTML的解析,直到脚本执行完成。如果脚本较大或网络较慢,这种阻塞会导致页面加载速度变慢,影响用户体验。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="example.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
在上面的例子中,浏览器在解析到<script src="example.js"></script>时会暂停HTML解析,等待脚本下载和执行完成后,才继续解析剩余的HTML内容。这种默认行为会导致页面加载的延迟。理解这一点对于理解asyncdefer属性的作用至关重要。

浏览器解析过程中的阻塞

默认情况下,当浏览器遇到一个没有任何属性的<script>标签时,解析过程如下:
  1. 停止解析HTML。
  2. 开始下载JavaScript文件。
  3. 下载完成后,执行JavaScript文件。
  4. 继续解析HTML。
如果一个页面包含多个这样的<script>标签,浏览器会多次重复上述过程,每个脚本都会导致解析过程的阻塞。对于包含大量或较大JavaScript文件的页面,这种阻塞会显著影响页面加载时间,导致较差的用户体验。

二、async属性

async属性用于告诉浏览器异步加载脚本文件,即不阻塞HTML的解析。加载完成后立即执行该脚本。这意味着脚本的执行顺序不一定按照它们在HTML中的出现顺序,而是取决于它们的加载完成时间。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script async src="example.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
在上述示例中,浏览器在遇到<script async src="example.js"></script>时会继续解析HTML,同时在后台异步下载example.js。当脚本下载完成后,会立即执行它,而不管HTML解析是否完成。

async的工作机制

  1. 浏览器开始解析HTML。
  2. 遇到带有async属性的<script>标签时,继续解析HTML,并开始异步下载JavaScript文件。
  3. 下载完成后,立即执行JavaScript文件。
  4. 执行完成后,继续先前的解析过程(如果尚未完成)。

适用场景

async属性适用于独立的脚本文件,这些脚本不依赖于其他脚本,也不依赖于DOM的结构。例如,统计脚本或广告脚本等可以使用async属性。这类脚本通常不影响页面的主要功能和布局,只是提供附加功能,因此它们可以独立加载和执行,不会影响页面的其他部分。

async的优点和缺点

优点:
  • 不阻塞HTML解析,加快页面初始加载速度。
  • 加载完成后立即执行,确保脚本尽早生效。
缺点:
  • 执行顺序不确定,适合独立脚本,不能用于有依赖关系的脚本。

三、defer属性

defer属性同样用于异步加载脚本文件,但与async不同的是,defer确保脚本在HTML解析完成后,按顺序执行。这样可以保证所有defer脚本按照它们在文档中出现的顺序执行,并且不会阻塞HTML的解析过程。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script defer src="example1.js"></script>
<script defer src="example2.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
在上述示例中,example1.jsexample2.js会在HTML解析完成后按顺序执行,确保脚本的执行顺序与它们在文档中的顺序一致。

defer的工作机制

  1. 浏览器开始解析HTML。
  2. 遇到带有defer属性的<script>标签时,继续解析HTML,并开始异步下载JavaScript文件。
  3. 下载完成后,等HTML解析完成,再按顺序执行所有defer脚本。

适用场景

defer属性适用于需要按顺序执行的脚本,尤其是那些依赖于DOM结构或其他脚本的脚本。例如,初始化页面的脚本或依赖于库的脚本适合使用defer属性。通过确保脚本在DOM解析完成后执行,可以避免脚本在DOM尚未准备好时执行,导致的错误和问题。

defer的优点和缺点

优点:
  • 不阻塞HTML解析,加快页面初始加载速度。
  • 保证脚本按顺序执行,适合有依赖关系的脚本。
缺点:
  • 脚本执行时间稍晚,适用于需要依赖完整DOM的脚本。

四、async与defer的比较

加载方式异步加载异步加载
执行时机加载完成后立即执行HTML解析完成后执行
执行顺序不保证顺序,谁先加载完成谁先执行保证顺序,按照在HTML中的出现顺序执行
适用场景独立脚本,如统计脚本或广告脚本依赖于DOM或其他脚本的脚本,如初始化脚本

示例

假设我们有两个脚本文件script1.jsscript2.js,如果我们使用asyncdefer,它们的行为会有所不同:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Async vs Defer</title>
<!-- 使用async -->
<script async src="script1.js"></script>
<script async src="script2.js"></script>
<!-- 使用defer -->
<script defer src="script3.js"></script>
<script defer src="script4.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

在上述示例中:

  • script1.jsscript2.js会异步加载,但谁先加载完成就先执行,因此无法保证执行顺序。
  • script3.jsscript4.js会在HTML解析完成后按顺序执行,确保执行顺序与它们在文档中的顺序一致。

五、适用建议

  1. 独立脚本使用async:对于不依赖DOM结构或其他脚本的独立脚本,例如统计工具、广告脚本等,使用async属性可以加快这些脚本的加载和执行,同时不影响页面的主要内容加载。
  2. 依赖顺序的脚本使用defer:对于依赖于其他脚本或DOM结构的脚本,例如初始化脚本、库文件等,使用defer属性可以确保它们在HTML解析完成后按顺序执行,避免因为依赖关系导致的错误。
  3. 组合使用:在一个页面中,可以组合使用asyncdefer,根据具体脚本的需求选择合适的属性,以达到最佳的性能优化效果。
通过合理使用asyncdefer属性,可以显著优化Web页面的加载性能和用户体验。async适用于独立且不依赖其他资源的脚本,而defer适用于需要按顺序执行且可能依赖于DOM或其他脚本的脚本。
© 2010-2022 XuLaLa 保留所有权利 本站由 WordPress 强力驱动
请求次数:69 次,加载用时:0.665 秒,内存占用:32.19 MB