不要再把script标签的`async`和`defer`的属性作用弄反了!!!

361 阅读2分钟

这是我参与8月更文挑战的第18天,活动详情查看:8月更文挑战

不要再把asyncdefer的作用弄反了!!!

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 被执行");

运行后我得到的结果是:

image-20210818204748827.png

加了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>

执行结果如下:

  • image-20210818205557688.png
  • image-20210818205627771.png
  • image-20210818205835461.png 我这里刷新了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网

image-20210818211022039.png

同步的效果也来看看,代码就不贴了,和上面一样,把defer属性去掉就行,结果就是js不加载完,div元素不出来

image-20210818211454947.png

对于这个测试有一个提醒点就是:一定要在首次加载时去看效果,第二次实验时需要把dom清除掉再进行(可以注释掉),避免页面保留上一次内容

总结

按使用需求来讲,大致可以分为三类

  • 需要立即执行,但是会阻塞,就不需要添加defer或者async属性

  • 仅仅需要异步加载,使用async

  • 需要异步加载,并且脚本顺序有要求,使用defer

不要再把asyncdefer的作用弄反了!!!!!

如有不对之处,欢迎指正✍