【JavaScript面试】script标签defer和async的区别

前言:

JavaScript代码的加载和执行会阻塞下面HTML的渲染。

为了解决这个问题就出现了

< script>标签提供了两个属性:defer和async。

没有 defer async 属性

<script src="script.js"></script>

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

defer 属性

<script defer src="script.js"></script>

当Script中有defer属性时,文档解析和脚本加载是异步的,等文档解析完脚本才开始执行。因此,在< script>元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。

async 属性

<script async src="script.js"></script>

当Script中有async 属性时,文档解析和脚本加载也是异步的,脚本下载完成后会停止HTML解析,执行脚本,脚本解析完继续HTML解析。

当 defer 和 async 同时存在时

执行效果和 async 一致

图解

在这里插入图片描述
概括来讲,就是这两个属性都会使script标签异步加载,然而执行的时机是不一样的。async是乱序的,而defer是顺序执行,这也就决定了async比较适用于百度分析或者谷歌分析这类不依赖其他脚本的库。从图中可以看到一个普通的< script>标签的加载和解析都是同步的,会阻塞DOM的渲染,这也就是我们经常会把< script>写在< body>底部的原因之一,为了防止加载资源而导致的长时间的白屏,另一个原因是js可能会进行DOM操作,所以要在DOM全部渲染完后再执行。

区别

相同点:

  • 加载文件时不阻塞页面渲染
  • 对于inline的script(内联脚本)无效
  • 使用这两个属性的脚本中不能调用document.write方法
  • 有脚本的onload的事件回调

不同点:

  • html的版本html4.0中定义了defer;html5.0中定义了async
  • 浏览器兼容性

总结

简单的来说,使用这两个属性会有三种可能的情况

  • 如果async为true,那么脚本在下载完成后异步执行。
  • 如果async为false,defer为true,那么脚本会在页面解析完毕之后执行。
  • 如果async和defer都为false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行。

猜你喜欢

转载自blog.csdn.net/qq_40992225/article/details/127647741