关于defer和async的原理

deferasync是script标签的两个属性,用于在不阻塞页面文档解析的前提下,控制脚本的下载和执行。在介绍他们之前,我们有必要先了解一下页面的加载和渲染过程:

页面的加载和渲染过程

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

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

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

  4. 完成文档解析后,将DOM和CSSDOM进行关联和映射,最后将视图渲染到浏览器窗口 在这个过程中,脚本文件的下载和执行是与文档解析同步进行,也就是说,它会阻塞文档的解析,如果控制得不好,在用户体验上就会造成一定程度的影响

defer和async的原理

640?wx_fmt=other

此图告诉我们以下几个要点:

  1. defer 和 async 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析)

  2. 它俩的差别在于脚本下载完之后何时执行,显然defer是最接近我们对于应用脚本加载和执行的要求的

  3. async 则是一个乱序执行的主,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行

所以相对于默认的script引用,这里配合defer和async就有两种新的用法,它们之间什么区别那?

  1.默认引用 script:<script type="text/javascript" src="x.min.js"></script>

  当浏览器遇到 script 标签时,文档的解析将停止,并立即下载并执行脚本,脚本执行完毕后将继续解析文档。

  2.async模式 <script type="text/javascript" src="x.min.js" async="async"></script>

  当浏览器遇到 script 标签时,文档的解析不会停止,其他线程将下载脚本,脚本下载完成后开始执行脚本,脚本执行的过程中文档将停止解析,直到脚本执行完毕。

  3.defer模式 <script type="text/javascript" src="x.min.js" defer="defer"></script>

  当浏览器遇到 script 标签时,文档的解析不会停止,其他线程将下载脚本,待到文档解析完成,脚本才会执行。

所以async和defer的最主要的区别就是async是异步下载并立即执行,然后文档继续解析,defer是异步加载后解析文档,然后再执行脚本,这样说起来是不是理解了一点了

关于defer我们需要注意下面几点:

  1. defer只适用于外联脚本,如果script标签没有指定src属性,只是内联脚本,不要使用defer

  2. 如果有多个声明了defer的脚本,则会按顺序下载和执行

  3. defer脚本会在DOMContentLoaded和load事件之前执行

关于async,也需要注意以下几点:

  1. 只适用于外联脚本,这一点和defer一致

  2. 如果有多个声明了async的脚本,其下载和执行也是异步的,不能确保彼此的先后顺序

  3. async会在load事件之前执行,但并不能确保与DOMContentLoaded的执行先后顺序

 热 文 推 荐 

☞ Webpack 应用瘦身

☞ 送你43道JavaScript面试题

☞ RDE - 一种基于Docker的前端生态集成解决方案

☞ 中高级前端必须了解的--JS中的内存管理

☞ CSS的一些你可能不知道的强大技巧

640?wx_fmt=png

640?wx_fmt=png

你也“在看”吗?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值