文章目录
- 为什么要异步加载
- 如何实现异步加载
- 参考
为什么要异步加载
两个原因其实是一个意思。
原因1:
JS是单线程的语言,它会同步的执行代码,从上往下执行
但是,一旦网络不好,或要加载的js文件过大的话,会造成页面阻塞,不利于后续的渲染工作,十分影响交互体验,此时,可以使用异步加载的方法解决这个问题。
原因2:
浏览器在解析HTML时,遇到script会先执行JS脚本,再构建DOM树。
原因是:
JS的作用之一是操作并修改DOM,若等到DOM树构建完成再渲染并执行JS,会造成严重的回流和重绘。
但在如今的开发模式中,JS往往比HTML内容更多,处理时间更长。若先执行完JS再执行HTML,会造成页面的解析阻塞,在JS执行完成之前,用户在页面上什么也看不到。这样是不好的。
因此,我们要用异步加载解决这个问题。
如何实现异步加载
async
defer
- 动态创建script标签
举例说明:
没有defer或async,浏览器会立即加载并执行指定的脚本。
<script src="script.js"></script>
有async
,加载和渲染后续文档元素的过程 与 script.js的加载和执行 并行(这就是异步)
<script async src="script.js"></script>
有defer
,加载和渲染后续文档元素的过程 与 script.js的加载和执行 并行,但是,script.js的执行要在所有元素解析完成之后,DOMContentLoaded事件触发之前完成。
<script defer src="myscript.js"></script>
如图:
绿色:HTML解析。
蓝色:网络请求脚本。
红色:执行脚本。
由图可知:
- 若没有
defer
或async
,当代码执行到script标签,就进行网络请求脚本和执行脚本,HTML的解析会停掉 - 若有
defer
,会在HTML继续解析的同时网络请求脚本,并且在HTML解析完成之后执行脚本 - 若有
async
,会在HTML继续解析的同时网络请求脚本,且脚本一旦下载完成就执行
由此可以看出async
和defer
的区别:执行脚本的时机不同。async在下载完成后立马执行js,而defer在HTML解析完成后执行js。
参考
如何实现JS异步加载 - 简书 (jianshu.com)
javascript异步加载的三种方式以及如何动态创建script标签_Choo01的博客-CSDN博客_动态script
【JavaScript高级】浏览器原理:渲染引擎解析页面步骤、回流和重绘、composite合成、defer与async_karshey的博客-CSDN博客
defer和async的区别(面试被问到了) - 掘金 (juejin.cn)
js异步加载——defer和async的区别 - sakuramoon - 博客园 (cnblogs.com)