如果没有defer或async属性,浏览器会立即向网络请求获取该JS脚本并执行,就阻塞了后续文档的解析。而 defer 和 async属性都是去异步加载外部的JS脚本文件,它们都不会阻塞页面的解析
二者区别:
- 执行顺序
-
- 多个async的script不能保证加载的顺序,依赖于网络传输结果,谁先到就先执行谁;
- 多个defer的script会按照html中出现的顺序先后执行;
- 脚本是否并行执行
-
- 后续文档的加载和执行与 js脚本的加载 (仅加载不执行)是并行进行(异步);
- 加载后续文档的过程和 js脚本的加载 (仅加载不执行)是并行进行的(异步),js脚本需要等到文档所有元素解析完成之后才执行,DOMContentLoaded事件触发执行之前。
- 是否阻塞html解析
-
- async:可能阻塞;
-
-
- 阻塞场景:网络请求到js脚本并返回之后,如果HTML还没有解析完全,HTML会暂停解析,先让JS引擎执行JS代码,执行完成后HTML再继续解析。
- 不阻塞:网络请求并返回JS脚本之后,如果THMLL已经解析完,立即执行JS脚本,不可能阻塞;
- 阻塞场景:网络请求到js脚本并返回之后,如果HTML还没有解析完全,HTML会暂停解析,先让JS引擎执行JS代码,执行完成后HTML再继续解析。
-
-
- defer:不阻塞
浏览器等待HTML解析完后才会执行JS代码。