异步加载JS—defer和async
为什么要异步加载JS
同步加载JS:将<script>脚本放在<head>标签内,不使用defer和async。这时浏览器碰到<script>标签会立即加载并执行指定的脚本,“立即”指的是在渲染 <script> 标签之下的文档元素之前,也就是说不再渲染后续的文档元素,直到<script>之内的元素加载并执行完毕。这样会造成 “空白页” 出现,给用户带来很不友好的体验,所以就出现了异步加载JS的办法;
异步加载JS:异步是相对于HTML解析来说的。即在加载<script>脚本的同时继续加载并渲染后续的HTML元素,即并行进行,该过程为异步加载JS;
异步加载JS有哪些方法
1、将<script>脚本放在</body>标签之前
注意,这并不是真正意义上的异步加载JS,而是利用HTML从上到下执行代码的特性,最后执行<script>脚本
但是,这是最佳实践。因为对于旧浏览器来说这是唯一的优化选择,此法可保证非脚本的其它一切元素能够以最快的速度加载并解析。
2、使用defer
<script defer src="demo1.js"></script>
<script defer src="demo2.js"></script>
demo1.js 和 demo2.js 将和后续文档元素的加载同时进行(加载并不等于执行);
demo1.js 和 demo2.js 的执行是在所有元素渲染完成之后,DOMContentLoaded事件触发之前完成;
demo1.js 和 demo2.js 会按照顺序执行,即先执行 demo1.js,再执行 demo2.js(因为demo1.js 在 demo2.js 之前);
注意:当脚本都加载完成后才会按照顺序执行
适用:当脚本之间有相互依赖时非常合适
3、使用async
<script async src="demo3.js"></script> <script async src="demo4.js"></script>
demo3.js 和 demo4.js 将和后续文档元素的加载同时进行(加载并不等于执行);
demo3.js 和 demo4.js 并不保证执行顺序,谁先加载完成谁先执行。即同一个js文件的执行紧挨着加载的,加载完毕就执行
demo3.js 和 demo4.js 可能在DOMContentLoaded事件之前执行,比如当HTML元素特别多时
也可能在DOMContentLoaded事件之后执行,比如当HTML元素特别少时
适用:对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的
写的比较偏理论,想看实践的,推荐一篇文章 https://www.cnblogs.com/jiasm/p/7683930.html。