首先来看看这三句话:

<script src="/UploadFiles/2021-04-02/script.js">

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

<script async src="/UploadFiles/2021-04-02/script.js">

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

<script defer src="/UploadFiles/2021-04-02/myscript.js">

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

下面来进行详解的介绍这二者的区别。

一般情况

按照惯例,所有script元素都应该放在页面的head元素中。这种做法的目的就是把所有外部文件(CSS文件和JavaScript文件)的引用都放在相同的地方。可是,在文档的head元素中包含所有JavaScript文件,意味着必须等到全部JavaScript代码都被下载、解析和执行完成以后,才能开始呈现页面的内容(浏览器在遇到body标签时才开始呈现内容)。

对于那些需要很多JavaScript代码的页面来说,这无疑会导致浏览器在呈现页面时出现明显的延迟,而延迟期间的浏览器窗口中将是一片空白。为了避免这个问题,现在Web应用程序一般都全部JavaScript引用放在body元素中页面的内容后面。这样一来,在解析包含的JavaScript代码之前,页面的内容将完全呈现在浏览器中。而用户也会因为浏览器窗口显示空白页面的时间缩短而感到打开页面的速度加快了。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title></title>
</head>
<body>
<script type="text/javascript" src="/UploadFiles/2021-04-02/script.js">

defer (延迟脚本)

延迟脚本:defer属性只适用于外部脚本文件。

如果给script标签定义了defer属性,这个属性的作用是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,如果script元素中设置了defer属性,相当于告诉浏览器立即下载,但延迟执行。

示例:

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>延迟加载</title>
 <script defer type="text/javascript" src="/UploadFiles/2021-04-02/test.js">

这个例子中,虽然我们把script元素放在了文档的head元素中,但其中包含的脚本将延迟到浏览器遇到</html>标签后再执行
HTML5规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContentLoaded事件(在DOM树构建完成后触发,不需要等到所有的资源都加载完毕)执行。

特别注意:在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoaded事件触发前执行,因此最好只包含一个延迟脚本。

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

最佳实践

从实用角度来说,把所有脚本都放在 </body> 之前是最佳实践,因为对于旧浏览器来说这是唯一的优化选择,此法可保证非脚本的其他一切元素能够以最快的速度得到加载和解析。

**注意:**defer属性在浏览器之间表现并不一致。为了避免跨浏览器的差异,可以使用 “lazy loading”的方法,即直到用到该脚本时才加载。

function lazyload() {
 var elem = document.createElement("script");
 elem.type = "text/javascript";
 elem.async = true;
 elem.src = "script.js"; 
 document.body.appendChild(elem);
}

if (window.addEventListener) {
 window.addEventListener("load", lazyload, false);
} else if (window.attachEvent) {
 window.attachEvent("onload", lazyload);
} else {
 window.onload = lazyload;
}

async(异步脚本)

异步脚本:async属性也只适用于外部脚本文件,并告诉浏览器立即下载文件。

但与defer不同的是:标记为async的脚本并不保证按照指定它们的先后顺序执行。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <title>异步加载</title>
 <script async type="text/javascript" src="/UploadFiles/2021-04-02/test1.js">

这个例子中,test2.js可能会在test1.js之前执行。因此,确保两者之间互不一来非常重要。指定async属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。因此,建议异步脚本不要在加载期间修改DOM。

来看一张更加清晰的图:

关于Javascript中defer和async的区别总结

图解:蓝色线代表网络读取,红色线代表执行时间,这两个都是针对脚本的;绿色线代表 HTML 解析。

通过上图和之前的分析,我们可以得出:

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

      2、两者的差别:在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的。defer是立即下载但延迟执行,加载后续文档元素的过程将和脚本的加载并行进行(异步),但是脚本的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。async是立即下载并执行,加载和渲染后续文档元素的过程将和js脚本的加载与执行并行进行(异步)。

      3、关于 defer,我们还要记住的是它是按照加载顺序执行脚本的

      4、标记为async的脚本并不保证按照指定它们的先后顺序执行。对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行。

      5、async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的。

总结

以上就是关于js中defer和async区别的全部内容,文章介绍的很详细,希望能对大家的学习或者工作带来一定的帮助,如果有疑问大家可以留言交流。

标签:
js,defer,async,defer和async的区别,js,defer和async

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“关于Javascript中defer和async的区别总结”
暂无“关于Javascript中defer和async的区别总结”评论...

《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线

暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。

艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。

《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。