一文搞定script脚本加载顺序,说说defer和async

我们先来看一段代码,html中使用script标签引入了script1.js、script1.js和script3.js三个文件。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>TEST HTML</title>
  </head>
  <script src="script1.js"></script>
  <script src="script2.js"></script>
  <script src="script3.js"></script>
  <body>
    <p>test</p>
  </body>
</html>

我们开发的时候一般都说要把 <script> 放到 body体的最后,也就是 </body>之前,你要是不理解为什么这么做的话,我们来看浏览器遇到了上面这段代码,它是怎么干活的。

在这里插入图片描述

  1. 浏览器会解析HTML,一直到 script 标签,也就是这部分代码,对应上图中的蓝线

    <!DOCTYPE html>
    <html lang="ja">
      <head>
        <meta charset="utf-8">
        <title>TEST HTML</title>
      </head>
    
  2. 遇到了script 会通过src找到对应的js文件,进行下载(绿线),加载完成会执行(红线),注意,注意这个时候html是不会向下解析的,一直等到所有的script文件执行完成

    <script src="script1.js"></script>
    <script src="script2.js"></script>
    <script src="script3.js"></script>
    
  3. 然后解析剩下的html (蓝线

    <body>
        <p>test</p>
      </body>
    </html>
    

第二步加载JavaScript会阻碍html的解析,如果js文件很大,我们会一直等到js文件执行完了,解析后面的html我们才能在浏览器中看到页面,还有一个要是js中操作dom元素的话,很抱歉这个时候html都没解析完,找不到操作的元素。是不是理解为什么要把script放到最后了?script脚本阻碍html解析,阻碍时间长了就出现白屏了。

defer

修改之前的代码,script标签添加defer属性

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>TEST HTML</title>
  </head>
  <script src="script1.js" defer></script>
  <script src="script2.js" defer></script>
  <script src="script3.js" defer></script>
  <body>
    <p>test</p>
  </body>
</html>

脚本会被延迟到整个页面都解析完毕后再执行,如下图:
在这里插入图片描述

  1. 同之前一样,浏览器会解析HTML,一直到 script 标签
  2. 遇到script标签同时有defer属性,脚本文件会加载,但是html继续解析
  3. 等待html解析完毕,script中的代码开始执行

async

我们来看另一个属性async,修改代码为:

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>TEST HTML</title>
  </head>
  <script src="script1.js" async></script>
  <script src="script2.js" async></script>
  <script src="script3.js" async></script>
  <body>
    <p>test</p>
  </body>
</html>

脚本文件会在下载完成后执行
在这里插入图片描述

  1. 同之前一样,浏览器会解析HTML,一直到 script 标签
  2. 遇到script标签同时有async属性,脚本文件会加载,但是html继续解析
  3. 只要任意一个带有async的script脚本先加载完毕,就会直接执行,各个文件的执行顺序不定

同时添加defer和async

  • 表现和async一致

  • 不支持async的浏览器,支持defer的,会表现得和defer一样

    • 异步加载 比延迟执行的 优先级高些
  • 这种方法,是同时兼容 支持async和defer 两个属性的浏览器的一种办法

  • 如果 script 无 src 属性,则 defer, async 会被忽略

最后

还是回到最初的那个问题:为什么要把把<script>写在<body>底部?
因为这样,没有兼容性问题,没有白屏问题,没有执行顺序问题。就一句:可以放心下班了。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值