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

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

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

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

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

  • 由图得知:

  1. defer 和 async 在网络读取(下载)这部分是一样的,都是异步的(相较于 HTML 解析)。
    两者的差别在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的。

  2. 关于 defer,由图知它是按照加载顺序执行脚本的,这一点要善加利用。
    async 则是乱序执行,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行。

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


  • 下面来说明一下两者之间的不同:
      正常情况下,当浏览器在解析HTML源文件时如果遇到外部的script,那么解析过程会暂停,并发送请求来下载script文件,只有script完全下载并执行后才会继续执行DOM解析。
      那么如果一个页面有很多的外链的脚本。放在head中,那么加载脚本的时候就会阻塞页面的渲染,出现空白的现象。在简单的开发环境中可能调整一下js的位置就能解决问题。但是在越来越复杂的开发环境下,如果想调整js脚本的位置可能就要花费大量的时间。所以为了让这种成本降低。可以使用defer属性。
      如果一个script加了defer属性,即使放在head里面,它也会在html页面解析完毕之后再去执行,也就是类似于把这个script放在了页面底部。
      对于async,这个是html5中新增的属性,它的作用是能够异步的加载和执行脚本,不因为加载脚本而阻塞页面的加载。一旦加载到就会立刻执行。

  • 两者的相同点
    加载文件时不阻塞页面渲染。
    对于inline的script无效。
    使用这两个属性的脚本中不能调用document.write方法。
    有脚本的onload的事件回调。

  • 不同点
    html4.0中定义了defer,html5.0中定义了async。
    async属性的脚本会在下载结束后立刻执行,同时会在window的load事件之前执行,所以就会出现顺序被打乱的情况;defer属性的脚本是在页面解析完成后,按照顺序执行,同时会在document的DOMContentLoaded之前执行。
    总体来说,defer和async的主要不同就是defer会保证脚本的顺序,async不保证顺

作者:饥人谷_Shirley
链接:https://www.jianshu.com/p/757f56ebe5e1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

JS中关于async和defer作用与区别相关推荐

  1. script标签中的async和defer

    在程序中代码是一行一行执行的,html标签都是由渲染引擎来执行,代码执行时从上往下一行一行执行,当执行到alert(如下图),alert会阻塞后面代码的执行,当点击完确定之后,代码继续往下执行. ja ...

  2. php中jquery ajax请求参数,浅谈Jquery中Ajax异步请求中的async参数的作用

    之前不知道这个参数的作用,上网找了前辈的博客,在此收录到自己的博客,希望能帮到更多的朋友: test.html asy.js function testAsync{ var temp; $.ajax( ...

  3. 掌握Node.js中的Async和Await

    在本文中,你将学习如何使用Node.js中的async函数(async/await)来简化callback或Promise. 异步语言结构在其他语言中已经存在了,像c#的async/await.Kot ...

  4. js中的波浪线符号作用(按位非(~)符号)

    js中的波浪线符号作用(按位非(~)符号) 一.输入为正数(1和2) 二.输入为负数(-1,-2) Javascript 按位取反运算符 (~) ,对一个表达式执行位非(求非)运算.如 ~1 = -2 ...

  5. Spring中SmartLifecycle和Lifecycle的作用和区别

    欢迎关注方志朋的博客,回复"666"获面试宝典 本文基于SpringBoot 2.5.0-M2讲解Spring中Lifecycle和SmartLifecycle的作用和区别,以及如 ...

  6. ANDROID 中UID与PID的作用与区别

    ANDROID 中UID与PID的作用与区别 PID:为Process Identifier, PID就是各进程的身份标识,程序一运行系统就会自动分配给进程一个独一无二的PID.进程中止后PID被系统 ...

  7. linux中export和source的作用和区别

    linux中export和source的作用和区别 2013-11-12 12:36 1039人阅读 评论(0) 收藏 举报 分类: linux(82) shell与export命令 用户登录到Lin ...

  8. css里面的let,js中let和var定义变量的区别

    javascript 严格模式 第一次接触let关键字,有一个要非常非常要注意的概念就是"javascript 严格模式",比如下述的代码运行就会报错: let hello = ' ...

  9. js中的typeof 与typescript typeof的区别

    js中的typeof 与typescript typeof的区别 在 JavaScript 中,typeof 是一个运算符,用于返回一个值的数据类型.它可以返回下列字符串中的一个: "und ...

最新文章

  1. 源码安装tensorflow
  2. rust实战入门到进阶(1)
  3. 浅析phpwind9.0之登陆机制
  4. javascript字典中添加数组_如何在 JavaScript 中更好地使用数组
  5. How to: Create and Initialize Trace Listeners
  6. Android:Eclipse如何删除ADT
  7. 长城汽车旗下品牌“欧拉好猫”涉嫌虚假宣传 曾召回部分欧拉汽车
  8. 【转】Hbase之shell命令的使用
  9. 快速创建UI控件的 方法 ,值得总结1
  10. 62. Using Default Magento Cache
  11. 01【C3D 行为识别】项目下载 环境配置 数据集转化视频帧 UCF101数据集处理
  12. git/gitgub
  13. 芝麻信用分怎么提高到750+芝麻信用分暴涨攻略
  14. 常见的浏览器以及内核
  15. TortoiseGit assume-unchanged的文件怎么恢复
  16. ARIMA时间序列分析——(一)数据平稳性检验
  17. js和jsp的区别和联系
  18. 视频的帧率和分辨率以及码率的关系
  19. Cannot resolve com.oracle:ojdbc6:11.2.0.3
  20. 点名器实现的随机原理(实现随机点名器)

热门文章

  1. 软件测试技能大赛教学平台
  2. 转向灯c语言程序框图,科目一10道灯光题汇总,做完科三灯光操作也省事啦!
  3. 校园网自动pppoe拨号+Web认证
  4. php用户管理拿shell,PHPWEB网站管理系统后台拿shell
  5. 7-3 逆序的三位数 (c语言)
  6. VNote: 程序员的Markdown笔记软件
  7. 20145239杜文超《网络对抗》- Web安全基础实践
  8. Java架构师技术进阶路线图
  9. UML建模——使用EA工具开发时序图实践及经验
  10. 企业级实战大数据课程(五)-尹成-专题视频课程