script 上添加 defer、async 的区别
什么都不加
<script src="###"></script>
遇到这样的 script 标签,html 会暂停解析,先去请求 script 加载的资源,然后 js 引擎会执行其中的代码,执行完成之后恢复 html 解析。
多个 script 执行顺序:按照 html 中的顺序执行。
缺点:如果 script 标签放在 html 的头部,那么会阻塞 html 的解析,网络太慢或者 js 执行时间过长,都会导致页面长时间白屏。
添加 async
<script src="###" async></script>
异步请求脚本资源。script 加载的资源是异步请求的,不会阻塞 html 的渲染,但是资源回来之后,html 解析会暂停,去执行 js ,执行完成之后再回复 html 解析。
多个 script 执行顺序:依赖网络,谁先加载完成谁先执行。
缺点:因为执行时间不确定,因此在 js 中获取 dom 元素的话,有可能会获取不到
添加 defer
<script src="###" defer></script>
异步请求脚本资源。script 加载的资源是异步请求的,不会阻塞 html 的渲染,但是资源回来之后,html 解析不会暂停,待 html 解析完成之后再去执行 js。
多个 script 执行顺序:按照在 html 中出现的顺序执行
将脚本放在 body 底部和 defer 的区别
如果脚本放在 body 底部,前者不能提前加载脚本,async 和 defer 都可以在页面渲染的同时加载资源
同时存在 async 和 defer
相当于只有 async
使用场景
- async:埋点分析这种不依赖其他脚本的库
- defer:效果类似于将资源放在 body 底部,如果不得已只能将资源放在 header 上的话,那可以给资源加上 defer 属性