这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战
不要再把
async
和defer
的作用弄反了!!!
defer属性
下面我引入两个脚本,其中在前面的一个脚本我加了defer
属性
demo1 / demo2文件已放远程地址上,可以自行测试
<script type="text/javascript" src="http://juliya.icu/static_dist/js/demo1.js" defer></script>
<script type="text/javascript" src="http://juliya.icu/static_dist/js/demo2.js"></script>
<script type="text/javascript" src="./demo1.js" defer></script>
<script type="text/javascript" src="./demo2.js"></script>
两个文件的内容如下所示:
// demo1.js
console.log("demo1 被执行");
// demo2.js
console.log("demo2 被执行");
运行后我得到的结果是:
加了defer
属性的标签异步加载,demo2
先执行。这里有两个特点:
- 同步比异步的先执行,保证同步的在前面;
- 同种类型的导入前面的比后面的先执行,异步加载的也有这个特点,顺序不会乱。
async属性
同样我也引入上面的文件做async
属性的测试
<script type="text/javascript" src="http://juliya.icu/static_dist/js/demo1.js" async></script>
<script type="text/javascript" src="http://juliya.icu/static_dist/js/demo2.js"></script>
<script type="text/javascript" src="./demo1.js" async></script>
<script type="text/javascript" src="./demo2.js"></script>
执行结果如下:
-
我这里刷新了10来次,出现了这几种组合,理论上我觉得应该还有其它组合,但这也能总结出以下两点:
-
这也是异步加载的一种方式
-
但是
async
属性并不能保证顺序!!
阻塞
对于阻塞我也做了个测试,说明这两个属性还是非常好用的。
把导入脚本的顺序提到body
前
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style>
div {
width: 100px;
height: 100px;
background-color: pink;
}
</style>
<script
type="text/javascript"
src="http://juliya.icu/static_dist/js/demo1.js"
defer
></script>
<script
type="text/javascript"
src="http://juliya.icu/static_dist/js/demo2.js"
defer
></script>
<body>
<div></div>
</body>
</html>
因为添加了defer
属性,来看下效果,此时脚本还在请求,div元素被正常加载出来了,异步效果 nice啊!这里我用了3G网
同步的效果也来看看,代码就不贴了,和上面一样,把defer属性去掉就行,结果就是js不加载完,div元素不出来
对于这个测试有一个提醒点就是:一定要在首次加载时去看效果,第二次实验时需要把dom清除掉再进行(可以注释掉),避免页面保留上一次内容
总结
按使用需求来讲,大致可以分为三类
-
需要立即执行,但是会阻塞,就不需要添加
defer
或者async
属性 -
仅仅需要异步加载,使用
async
-
需要异步加载,并且脚本顺序有要求,使用
defer
不要再把async
和defer
的作用弄反了!!!!!
如有不对之处,欢迎指正✍