script标签中的async,defer属性
script标签中的async,defer属性
script标签中的async,defer属性一、有无async,defer属性的含义
1、<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
2、<script async src="script.js"></script>
(1)、有 async,浏览器会立即下载脚本,但不妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本。加载和渲染后续文档元素的过程和script.js的加载与执行并行进行(异步)。
(2)、async不保证按照脚本出现的先后顺序执行,因此,确保两者之前互不依赖非常重要,指定async属性的目的是不让页面等待两个脚本的下载和执行,从而异步加载页面其他内容,建议异步脚本不要在加载期间修改DOM。
(3)、异步脚本一定会在页面的load事件前执行,但可能会在DOMContentLoaded事件触发之前或之后执行。
3、<script defer src="script.js"></script>
有 defer, 表示脚本会被延迟到文档完全被解析和显示之后再执行,加载后续文档元素的过程将和script.js的加载并行进行(异步)。
二、浏览器的在遇到defer和async属性的<script>的执行过程如下
1、WEB浏览器创建Document对象,并且开始解析WEB页面,解析HTML元素和它们的文本内容后添加Element对象和Text节点到文档中。这个过程的readystate的属性值是“loading”
2、当HTML解析器遇到没有async和defer属性的<script>时,它把这些元素添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载(如果需要)和执行解析器会暂停。这样脚本就可以用document.write()来把文本插入到输入流中。解析器恢复时这些文本会成为文档的一部分。同步脚本经常单定义函数和注册后面使用的注册事件处理程序,但它们可以遍历和操作文档树,因为在它们执行时已经存在了。这样同步脚本可以看到他自己的<script>元素和它们之前的文档内容
3、当解析器遇到了设置async属性的<script>元素时,它开始下载脚本,并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器没有停下来等他下载。异步脚本禁止document.write()方法。它们可以看到自己的<script>元素和它之前的所有文档元素,并且可能或干脆不可能访问其他的文档内容。
4、当文档完成解析,document.readyState属性变成“interactive”。
5、所有有defer属性的脚本,会被它们在文档的里的出现顺序执行。异步脚本可能也会在这个时间执行。延迟脚本能访问完整的文档树,禁止使用document.write()方法。
6、浏览器在Document对象上触发DOMContentLoaded事件。这标志着程序执行从同步脚本执行阶段转到异步事件驱动阶段。但要注意,这时可能还有异步脚本没有执行完成。
7、这时,文档已经完全解析完成,但是浏览器可能还在等待其他内容载入,如图片。当所有这些内容完成载入时,并且所有异步脚本完成载入和执行,document.readyState属性变为“complete”,WEB浏览器出发Window对象上的load事件。
8.从此刻起,会调用异步事件,以异步响应用户输入事件,网络事件,计算器过期等。
三、defer和async的比较
1、相同点
(1)、加载文件时不阻塞页面渲染;
(2)、对于inline的script无效;
(3)、使用这两个属性的脚本中不能调用document.write方法;
(4)、有脚本的onload的事件回调;
(5)、允许不定义属性值,仅仅使用属性名;
2、不同点
(1)、每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;
(2)、每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。
- js原生tab栏切换(JavaScript实现简易tab栏切换案例)
- JavaScript 常用的开发规范
- qt和js相互调用(QT与javascript交互数据的实现)
- redux实例教程(详解JavaScript状态容器Redux)
- js使用canvas(JavaScript canvas实现七彩时钟效果)
- js使用递归解析(关于JavaScript递归经典案例题详析)
- javascript作用域实例(JavaScript defineProperty如何实现属性劫持)
- javascript如何跨域
- javascript 数据分析(利用JavaScript差集实现一个对比小工具)
- jsfor循环是什么意思(JavaScript中三种for循环语句的使用总结for、for...in、for...of)
- javascript 开发网站(帮你提高开发效率的JavaScript20个技巧)
- javascript构造重复数组(JavaScript平铺数组转树形结构的实现示例)
- js闭包可以解决哪些问题(JavaScript中let避免闭包造成问题)
- javascript中error错误类型
- javascript弹出菜单(Javascript实现简易导航栏)
- js三级联动说明(基于JavaScript实现省市联动效果)
- 硕博期刊 SCI SSCI CSSCI分不清 一文带你看懂主流期刊分类(硕博期刊SCISSCI)
- 辱华品牌新百伦官宣新代言人IU,个别粉丝希望get爱豆同款(辱华品牌新百伦官宣新代言人IU)
- 巅峰时期被爆床照,曾被选国民最讨厌女星,IU不为人知的黑历史(巅峰时期被爆床照)
- 每天1万吨牛奶倒进下水道,美国大萧条一幕重现(每天1万吨牛奶倒进下水道)
- 如何看待美国数十万加仑牛奶倒下水道 历史又重演了(如何看待美国数十万加仑牛奶倒下水道)
- 历史惊人的相似,美国80万加仑牛奶倒入下水道,意味着什么(历史惊人的相似)
热门推荐
- mysql 索引怎么实现(Mysql中索引和约束的示例语句)
- mysql8.0.19.0正确安装图解(MySQL 8.0.23 主要更新一览新特征解读)
- sql server中使用xp_readerrorlog查看错误日志
- dede标签调用方法(DEDE热门tag,DEDE首页digg,DEDE随机热门关键字调用方法)
- docker如何加volume(Dockerfile 中 VOLUME 与 docker -v 的区别说明)
- sql server操作方法(SQL Server 文件操作方法)
- sql如何把现有字段设为notnull(在SQL中该如何处理NULL值)
- mysql索引原理及调优(MySQL索引机制程序员必知)
- css3渐变背景教程(css3实现背景图片颜色修改的多种方式)
- 用python画圣诞树送给女朋友(情人节快乐! python绘制漂亮玫瑰花)