前言
之前面试问的比较细,问资源提示符,问到了async和defer的执行顺序的问题,被卡住了,今天专门查了下MDN和HTML标准文档,整理了一下,也分享出来,希望对大家有用
基本作用
简单带过一下基本作用
async: 让js在下载后立即执行,下载过程不阻塞HTML解析(下载过程是异步)defer: 让js在下载后先不执行,在dom解析完成后,但在触发DOMContentLoaded事件之前执行。下载过程不阻塞HTML解析(下载过程是异步)
执行顺序
首先有个属性的覆盖问题
特殊属性
blocking: script 标签的 blocking 属性是 render 的时候,会让js下载完之后立即执行且下载和执行都可能会阻塞渲染但是不会阻塞HTML解析,因为需要等脚本执行了才能开始渲染 
async和defer之间的属性优先级
(在当前浏览器支持async的情况下)
根据HTML标准文档 : 如果一个普通标签同时有async和defer,那么async会覆盖defer 
(在当前浏览器只支持defer不支持async的情况下)
根据HTML标准文档 : 当前标签同时有defer和async,则会支持defer 
内联脚本
内联脚本就是没有设置src的script标签,你写的内联的js
根据MDN描述:内联脚本对 async 和 defer 都不生效

正常情况下的执行顺序逻辑
我简化一下情况,好进行描述,正常情况就是没有上面说的这些情况:
1.无特殊属性;2.一个标签只有defer或者async;3.浏览器两个都支持;4.有src
经典脚本
根据MDN文档:
async因为都是并发的,所以执行相对顺序不确定 ,下载完就会立即执行
defer是下载是并发,但是执行是在DOMContentLoaded事件之前,defer标签之间相对顺序是按照标签的顺序 来的,所以defer标签之间可以有依赖

模块脚本
就是
<script type="module"></script>
根据 HTML标准文档:
- 在模块脚本中,defer没有用
- 在模块脚本中,加了async,那么也是并行下载,但是不止是当前脚本,而是当前脚本依赖的其他js都会进行并行下载并在下载完成之后执行
