JS中关于async和defer作用与区别(简洁易懂)

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

没有 defer 或 async浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

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

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

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

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

下面来说明一下两者之间的不同:

  正常情况下,当浏览器在解析HTML源文件时如果遇到外部的script,那么解析过程会暂停,并发送请求来下载script文件,只有script完全下载并执行后才会继续执行DOM解析。

  那么如果一个页面有很多的外链的脚本。放在head中,那么加载脚本的时候就会阻塞页面的渲染,出现空白的现象。在简单的开发环境中可能调整一下js的位置就能解决问题。但是在越来越复杂的开发环境下,如果想调整js脚本的位置可能就要花费大量的时间。所以为了让这种成本降低。可以使用defer属性。

如果一个script加了defer属性,即使放在head里面,它也会在html页面解析完毕之后再去执行,也就是类似于把这个script放在了页面底部

对于async,这个是html5中新增的属性,它的作用是能够异步的加载和执行脚本,不因为加载脚本而阻塞页面的加载。一旦加载到就会立刻执行。

两者的相同点

加载文件时不阻塞页面渲染。

对于inline的script无效。

使用这两个属性的脚本中不能调用document.write方法。

有脚本的onload的事件回调。

不同点

html4.0中定义了defer,html5.0中定义了async。

当浏览器遇到带有 async 属性的 script 时,请求该脚本的网络请求是异步的,不会阻塞浏览器解析 HTML,一旦网络请求回来之后,如果此时 HTML 还没有解析完,浏览器会暂停解析,先让 JS 引擎执行代码,执行完毕后再进行解析而且如果存在多个 async 的时候,它们之间的执行顺序也不确定,完全依赖于网络传输结果,谁先到执行谁。

结论:虽然是异步加载,会阻塞dom元素的解析,并且执行顺序是无序的,谁先加载完谁先执行!有可能在DOMContentLoaded事件之前执行,也可能在DOMContentLoaded事件之后执行,但是一定在onload事件之前执行

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

defer属性的脚本是在页面解析完成后,按照顺序执行,同时会在document的DOMContentLoaded之前执行。

结论:虽然是异步加载,但是不会阻塞dom元素的解析,并且严格按照书写顺序执行!

总体来说,defer和async的主要不同就是defer会保证脚本的顺序,async不保证顺序

作用:

1.没有 defer 或 async,浏览器会立即加载并执行指定的脚本,也就是说不等待后续载入的文档元素,读到就加载并执行。

2.async 属性表示异步执行引入的 JavaScript,与 defer 的区别在于,如果已经加载好,就会开始执行——无论此刻是 HTML 解析阶段还是 DOMContentLoaded 触发之后。需要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发之前或之后执行,但一定在 onload 触发之前执行。

3.defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未停止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后触发 DOMContentLoaded 事件。

另外补充一下:

何时触发DOMContentLoaded , onload 这两个事件?

1、当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了。

2、当 DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash。

  • window.onload :页面全部加载完成包括图片
  • DOMContentLoad:dom渲染完成即可,此时图片视频可能还没有加载完

 注意:async和defer属性都仅适用于外部脚本,如果script标签没有src属性,尽管写了async、defer属性也会被忽略

总结

script 是会阻碍 HTML 解析的,只有下载好并执行完脚本才会继续解析 HTML

defer 和 async有一个共同点:下载此类脚本都不会阻止页面呈现(异步加载),区别在于:

  1. async 执行与文档顺序无关,先加载哪个就先执行哪个;defer会按照文档中的顺序执行
  2. async 脚本加载完成后立即执行,可以在DOM尚未完全下载完成就加载和执行;而defer脚本需要等到文档所有元素解析完成之后才执行

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值