html5中defer的属性,HTML5中defer和async的比较

本文详细探讨了在HTML中使用defer和async属性加载外部JavaScript脚本时的区别。defer属性确保脚本在DOM解析完成后执行,且按顺序执行多个脚本,而async属性则在脚本下载完成后立即执行,执行顺序不确定。因此,defer适合不依赖DOM的内容,而async适用于可以异步执行且不影响页面流程的脚本。在实际应用中,理解这两者的差异对于优化网页加载性能至关重要。
摘要由CSDN通过智能技术生成

在网站页面中,通常需要引入外部js资源,然而外部的js资源可能导致DOM阻塞,影响页面加载速度。通过异步或者延迟执行js,可以做到引用外部js资源而不阻塞DOM的目的。用法是直接在script标签中使用defer和async,那么它们两个有什么区别呢?

从字面上来理解,defer是延迟,而async则是异步(Asynchronous)。w3c上这样解释defer和async:defer属性是一个布尔值的属性,当存在这个属性时,它指定的脚本将在页面解析之后执行script标签的讲解。

概念的东西让人很难琢磨,下面是我对使用不同属性的外部引用标签的一个实验, 用php模拟一个外部javascript脚本:

header("Content-Type:text/javascript;charset=utf-8;");

sleep(2);

?>

console.log("This is the Script");

前台页面代码如下:

This is The Document.

下面的两张图片分别是使用defer和async的时间线:

fe82d835cd9aee6d31b0fc9f945af1f5.png

使用defer的时间线

7fce8c867a98f2191ba92b2e40875382.png

使用async的时间线

注意那条蓝色的时间线是DOMContentloaded时间,可以看到使用defer的DOMContentloaded事件是在JS脚本执行完之后,而使用async则是在html文档被解析完之后,相同之处是打印出”This is the Script”的时间一样。为什么会这样呢?

我们知道,如果javascript引入脚本既不使用defer也不使用async,整个页面是必须在引入脚本下载执行完毕之后才能继续被加载。而根据前面的概念,defer是延迟执行,async是异步执行。它们之间最大的区别是defer的执行时间是html文档被解析完成之后,而async的执行时间是不确定的,只要脚本被下载完毕,就会执行;它们之间的相同点是不会阻塞其它元素的加载。如果一个页面中有多个使用defer属性的外部脚本, 他们会按照顺序依次执行。

defer和async的应用

由于defer会在页面解析完成之后执行,所以当js脚本运行的时候,页面已经是解析完毕了的状态,这时候已经可以进行DOM操作, 而如果不使用defer,文档的状态不确定,所以不能进行操作。如上面的代码中,如果把js.php改成如下代码,打开前面页面,发现内容会被更改:

header("Content-Type:text/javascript;charset=utf-8;");

sleep(2);

?>

document.body.innerHTML="Body Content Has Been changed";

使用defer需要注意的是,由于defer的执行时机是页面解析完之后,含有defer的外部脚本执行时间是优先于内嵌脚本的,如下,内嵌脚本中放入一个DOMContentloaded的事件监听:

document.addEventListener("DOMContentLoaded",function(){

console.log("内部脚本,DOMContentloaded发生!");

},false);

>

This is The Document.

发现外部脚本内容先被打印出来。

而对于使用async的外部脚本来说,是在javascript文件被完全加载之后马上执行, 所以它可能会在DOM加载好之前被执行,也可能会在之后执行。这里的问题就是,如果异步加载的JS在DOM准备好之后执行,那么操作DOM的动作势必执行不了,如果在DOM准备好之前执行,则无法监听DOMContentloaded事件, 而依赖DOMContentloaded的事件回调就无法启动。例如一个HTML页面加入如下异步脚本代码:

header("Content-Type:text/javascript");

sleep(5);

?>

document.addEventListener("load",function(){

console.log('DOMContentLoaded Event');

},false);

发现”DOMContentLoaded Event”无法打印,而去掉async属性后,就会正常打印”DOMContentLoaded Event”, 这说明在异步加载后,外部脚本执行的时候,DOMContentLoaded事件已经过去。

综上,defer和async最大的区别是执行时间的不同,defer实在DOM解析完毕之后马上执行,而async是在脚本下载完毕之后马上执行。执行时机的不同造成最终的效果各不相同,在实际中要小心对待。

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值