async/defer 执行顺序全解析:从面试坑到 MDN 标准

前言

之前面试问的比较细,问资源提示符,问到了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都会进行并行下载并在下载完成之后执行
相关推荐
李剑一10 小时前
uni-app实现网络离线定位
前端·trae
鲨莎分不晴10 小时前
Nginx 部署前端项目实战指南
运维·前端·nginx
码界奇点10 小时前
基于Vue3与TypeScript的后台管理系统设计与实现
前端·javascript·typescript·vue·毕业设计·源代码管理
ashcn200111 小时前
水滴按钮解析
前端·javascript·css
攀登的牵牛花11 小时前
前端向架构突围系列 - 框架设计(五):契约继承原则
前端·架构
爱吃奶酪的松鼠丶11 小时前
React长列表,性能优化。关于循环遍历的时候,key是用对象数据中的ID还是用索引
javascript·react.js·性能优化
xkxnq11 小时前
第二阶段:Vue 组件化开发(第 17天)
javascript·vue.js·ecmascript
豆苗学前端11 小时前
你所不知道的前端知识,html篇(更新中)
前端·javascript·面试
一 乐11 小时前
绿色农产品销售|基于springboot + vue绿色农产品销售系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·后端·宠物
zzjyr11 小时前
Webpack 生命周期原理深度解析
前端