JS脚本加载中,defer和async的区别

JS脚本加载中,defer和async的区别
最新回答
长双眼皮的鱼

2020-06-27 01:48:28

JS脚本加载中,defer和async的区别

在HTML页面中插入JavaScript的主要方法包括内联脚本和外联脚本。内联脚本直接在页面中嵌入JavaScript代码,而外联脚本则引用外部JavaScript文件。在浏览器加载HTML过程中,遇到<script>标签时,默认情况下会阻塞HTML的解析和渲染,直到脚本被下载并执行完毕。这种行为被称为“渲染阻塞”。

为了解决这一问题,<script>标签提供了defer和async两个属性,它们允许浏览器异步加载脚本,从而避免阻塞HTML的解析和渲染。

1. async属性

  • 行为:async属性指示浏览器在允许的情况下异步执行脚本。对于没有src属性的内联脚本,async属性不起作用。
  • 执行时机:异步脚本会在下载完成后,尽快执行,但不一定在DOMContentLoaded事件触发之前或之后。此外,异步脚本的执行顺序不保证按照它们在HTML中出现的顺序。
  • 适用场景:适用于那些不依赖于其他脚本、不需要等待整个文档解析完成的独立脚本。

2. defer属性

  • 行为:defer属性通知浏览器,脚本将在文档完成解析后,但在DOMContentLoaded事件触发前执行。对于没有src属性的内联脚本,defer属性同样不起作用。
  • 执行时机:延迟脚本会在整个HTML文档解析完成后执行,且按照它们在HTML中出现的顺序执行。
  • 适用场景:适用于那些需要在文档解析完成后执行,但又不希望阻塞渲染过程的脚本。

3. 区别对比

  • 加载方式:async和defer都是异步加载脚本,不会阻塞HTML的解析和渲染。
  • 执行时机:async脚本在下载完成后尽快执行,可能在DOMContentLoaded事件之前或之后;而defer脚本在文档解析完成后执行,且保证执行顺序。
  • 对HTML解析的影响:async脚本在下载和执行时可能会中断HTML的解析和渲染;而defer脚本则不会,它会在文档解析完成后统一执行。
  • 适用场景:async更适合于独立、不依赖于其他脚本的异步任务;而defer更适合于需要在文档解析完成后按顺序执行的脚本。

4. 示例说明

通过Chrome的performance工具可以观察到,使用async和defer属性的脚本在加载和执行过程中的不同表现。

  • 对于async脚本,浏览器的HTML解析和脚本下载是并行的,但脚本的执行可能会中断HTML的渲染。
  • 对于defer脚本,浏览器的HTML解析和脚本下载同样是并行的,但脚本的执行会在文档解析完成后进行,且不会中断HTML的渲染。

总结

  • async和defer都是用于异步加载JavaScript脚本的属性,但它们在执行时机和对HTML解析的影响上有所不同。
  • 选择使用哪个属性取决于脚本的具体需求和依赖关系。如果脚本需要尽快执行且不需要等待文档解析完成,可以使用async;如果脚本需要在文档解析完成后按顺序执行,可以使用defer。