defer 和 async的区别

页面的加载和渲染过程

1.浏览器通过HTTP协议请求服务器,获取HMTL文档并开始从上到下解析,构建DOM;

2.在构建DOM过程中,如果遇到外联的样式声明和脚本声明,则暂停文档解析,创建新的网络连接,并开始下载样式文件和脚本文件;

3.样式文件下载完成后,构建CSSDOM;脚本文件下载完成后,解释并执行,然后继续解析文档构建DOM;

4.完成文档解析后,将DOM和CSSDOM进行关联和映射,最后将视图渲染到浏览器窗口 。

在这个过程中,脚本文件的下载和执行是与文档解析同步进行,也就是说,它会阻塞文档的解析,如果控制得不好,在用户体验上就会造成一定程度的影响。

script 标签中的 async 和 defer 属性

1.没有使用asyc 和 defer

浏览器在解析 HTML 的时候,如果遇到一个没有任何属性的 script 标签,就会暂停解
析,先发送网络请求获取该 JS 脚本的代码内容,然后让 JS 引擎执行该代码,当代码执行完毕后恢复解析。
可以看到,script 阻塞了浏览器对 HTML 的解析,如果获取 JS 脚本的网络请求迟迟得不到响应,或者 JS 脚本执行时间过长,都会导致白屏,用户看不到页面内容。

    <script src="script.js"></script>

image

2.使用async

当浏览器遇到带有 async 属性的 script 时,请求该脚本的网络请求是异步的,不会阻
塞浏览器解析 HTML,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器会暂
停解析,先让 JS 引擎执行代码,执行完毕后再进行解析,
当然,如果在 JS 脚本请求回来之前,HTML 已经解析完毕了,那就啥事没有,立即执行

<script async src="script.js"></script>
   

image

3.使用defer

当浏览器遇到带有 defer 属性的 script 时,获取该脚本的网络请求也是异步的,不会阻塞浏览器解析 HTML,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器不会暂停解析并执行 JS 代码,而是等待 HTML 解析完毕再执行 JS 代码

 <script defer src="myscript.js"></script>
    
//有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),
//但是 script.js 的执行要在所有元素解析完成之后,
//DOMContentLoaded 事件触发之前完成。

image

posted @ 2022-04-06 21:36  Kira的学习笔记  阅读(88)  评论(0编辑  收藏  举报