美文网首页
script上defer及async属性浅谈

script上defer及async属性浅谈

作者: 该帐号已被查封_才怪 | 来源:发表于2019-11-13 11:49 被阅读0次

当script上有defer或async属性时,script的下载均不会阻塞html的解析,但是一旦含有async属性的脚本被下载完,它就会立即执行(执行时会阻塞html的解析),而含有defer属性的脚本则是在html解析完后(DOMContentLoaded触发前)才执行;没有defer或async属性的脚本在下载时会阻塞html的解析,一旦其下载完它还会继续阻塞html的解析;具体可见下图:


image.png

图片来源 https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html

拿个超简单的页面测试一下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport">
   <title>Title</title>
  <script src="js/defer.js" defer></script>
  <script src="js/no.js"></script>
  <script src="js/async.js" async></script>

</head>
<body>
<div class="cainiao">测试script上defer及async属性</div>

<!--<script type="text/javascript">-->
<!--alert(str);//因为没有定义str,所以浏览器会出错,下面的不能运行-->
<!--alert("我是代码块一");//没有运行到这里-->
<!--var test = "我是代码块一变量";-->
<!--</script>-->
<!--<script type="text/javascript">-->
<!--alert("我是代码块二"); //这里有运行到-->
<!--alert(test);-->
<!--</script>-->

</body>
</html>

image.png

结果你可能觉得有点出乎意外,为什么defer会比async先执行?不是defer等到html解析完后才执行的吗?为什么它比async先执行? 其实仔细想想,defer是在html解析完后(DOMContentLoaded事件前)执行的,由于测试的页面比较简单,因此可能DOMContentLoaded事件完成后,async的脚本才下载完,所以async才被执行;当然这只是我们的分析,我们可以拿各个阶段的时间对比一下;接下来,我们来通过js获取相应的时间戳来验证这个想法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
  <meta content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0,user-scalable=no" name="viewport">
   <title>Title</title>
  <script>
    window.addEventListener('DOMContentLoaded',function () {
      console.log('DOMContentLoaded的时间戳是'+new Date().getTime())
    })
    function getAsyncLoadTime() {
      console.log('async load的时间戳是'+new Date().getTime())

    }
  </script>

  <script src="js/defer.js" defer></script>
  <script src="js/no.js"></script>
  <script src="js/async.js" async onload="getAsyncLoadTime()"></script>
</head>
<body>
<div class="cainiao">测试script上defer及async属性</div>

<!--<script type="text/javascript">-->
<!--alert(str);//因为没有定义str,所以浏览器会出错,下面的不能运行-->
<!--alert("我是代码块一");//没有运行到这里-->
<!--var test = "我是代码块一变量";-->
<!--</script>-->
<!--<script type="text/javascript">-->
<!--alert("我是代码块二"); //这里有运行到-->
<!--alert(test);-->
<!--</script>-->

</body>
</html>

image.png

上面的测试数据验证了我们的想法, 我后来刷新很多次,极少数也会出现下面的结果


image.png

拿个复杂一点的页面测试一下:

image.png

补充知识

1、JavaScript 的性能优化:加载和执行
2、你真的了解script标签吗?

相关文章

  • script上defer及async属性浅谈

    当script上有defer或async属性时,script的下载均不会阻塞html的解析,但是一旦含有async...

  • 第二章html中使用JavaScript

    没有 defer 或 async,浏览...

  • JavaScript高程读书笔记(1)

    一、script标签 async属性(只是适用于外部脚本文件)立即下载脚本,但不妨碍页面其他操作 defer属性(...

  • 浏览器script标签加载顺序

    script标签(不带defer或async属性)的会阻止文档渲染。相关脚本会立即下载并执行。 document....

  • 前端面试题集每日一练Day3

    问题先导 script标签中defer和async属性的区别?【html】 单行/多行文本溢出可以怎么处理?【cs...

网友评论

      本文标题:script上defer及async属性浅谈

      本文链接:https://www.haomeiwen.com/subject/ysbvbctx.html