<script /> async & defer

正常情况

<script src="app.js" />
  1. 停止解析 document
  2. 请求 app.js
  3. 执行 app.js 中的脚本
  4. 继续解析 document

也就是说正常情况下加载js文件和执行js文件是同步的会阻塞dom的解析

async

<script async src="app1.js" />
<script async src="app2.js" />
  1. 不阻止解析 document, 并行下载 app1.js,app2.js
  2. 当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在DOMContentLoaded事件前或者后 )

defer

<script defer src="app1.js" />
<script defer src="app2.js" />
  1. 不阻止解析 document, 并行下载 app1.js, app2.js
  2. 即使下载完 app1.js, app2.js 仍继续解析 document
  3. 按照页面中出现的顺序,在其他同步脚本执行后,DOMContentLoaded事件前 依次执行 app1.js, app2.js

关于DOMContentLoadedload事件

DOMContentLoaded 事件

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完成加载。另一个不同的事件 load 应该仅用于检测一个完全加载的页面。 在使用 DOMContentLoaded 更加合适的情况下使用 load 是一个令人难以置信的流行的错误,所以要谨慎。注意:DOMContentLoaded 事件必须等待其所属script之前的样式表加载解析完成才会触发。MDN地址

上面是mdn的解释,所以可以明白DOMContentLoaded事件在 html文档加载完毕,并且 html 所引用的内联 js、以及外链 js 的同步代码都执行完毕之后触发。

load 事件

当一个资源及其依赖资源已完成加载时,将触发load事件。MDN地址

对于DOM来讲,当页面 DOM 结构中的 js、css、图片,以及 js 异步加载的 js、css 、图片都加载完成之后,才会触发 load 事件。页面中引用的js 代码如果有异步加载的 js、css、图片,是会影响 load 事件触发的,而video、audio、flash 的加载则不会影响 load 事件触发