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都会进行并行下载并在下载完成之后执行
相关推荐
我的div丢了肿么办7 小时前
echarts中appendData的详细讲解
前端·javascript·vue.js
喝咖啡的女孩7 小时前
Web Worker 前端多线程解析
前端
一水鉴天7 小时前
整体设计 定稿 之6 完整设计文档讨论及定稿 之3 整体设计原则(原型-过程-模块三阶联动体系)
前端·数据库·人工智能
l1t7 小时前
Javascript引擎node bun deno比较
开发语言·javascript·算法·ecmascript·bun·精确覆盖·teris
静待雨落7 小时前
zustand持久化
前端·react.js
vivo互联网技术7 小时前
数字人动画云端渲染方案
前端·ffmpeg·puppeteer·web3d
go_caipu7 小时前
Vben Admin管理系统集成qiankun微服务
前端·vue.js
over6977 小时前
掌控 JavaScript 的 this:从迷失到精准控制
前端·javascript·面试
天才熊猫君7 小时前
基于 `component` 的弹窗组件统一管理方案
前端·javascript