如果script标签是引用的外部js文件, 那就会有一个下载js文件这一过程, 为了不因为这个下载过程而阻塞页面解析与渲染, 我们需要一种机制来解决这一问题, 方法之一就是使用 defer和async属性.

方法1. 使用 defer属性

defer属性的作用是延迟脚本的执行, 只有等到DOM生成之后才会执行脚本. 类似在DOMContentLoaded事件下添加监听函数.

// test1.js
// console.log(document.body.nodeName); // test1.html
<!DOCTYPE html>
<html lang="zh"> <head>
<script defer src="./test1.js"></script>
</head> <body>
</body> </html>

defer 属性的运行流程主要有下面几步: 

1. 浏览器下载的同时解析html

2. 发现带有defer的script标签时, 会在下载html的同时下载这个script标签的外部js文件

3. 下载并解析html完成后会触发 DOMContentLoaded事件, 但在这个事件触发之前, 带defer的js文件就会开始执行.

注意:

1. 多个带defer的script标签的最终执行顺序是跟它们在html中出现的先后顺序严格对应的

2. 对于不是加载外部js文件和动态生成的script文件, defer属性不生效

3. 使用defer加载的外部脚本不应该使用document.write()方法.

方法2. 使用async属性

async属性和defer属性都能解析加载script外部js文件引起的阻塞问题, 不过defer属性是在DOM载入完成以后才会执行, 而async是另开一个进程去下载脚本, 下载完成以后立刻执行, 执行的时候是会暂停解析的.

也就是说: async解决阻塞的方法是: 另开一个进程下载脚本, 这样就不会阻塞主进程html网页的解析.

// test1.js
// console.log("defer是DOM载入完成后执行.") // test2.js
// console.log("async是新开一个进程, 下载完成后就暂停主进程的解析, 执行下载的脚本.") <!DOCTYPE html>
<html lang="zh"> <head>
<script defer src="./test1.js"></script>
<script async src="./test2.js"></script>
</head> <body>
</body> </html>

注意: 

1. 使用async不能保证脚本的执行顺序, 而是谁先下载完, 就先执行谁, 因此async适用于脚本直接没有依赖关系的情况. 反之在用defer;

2. 如果一个scritp标签同时有defer和async属性, 则defer失效, script的行为由async决定;

3. 在脚本中还是不能使用document.write()方法.

总结起来, defer和async区别在于, 前者是在html解析完毕后按顺序执行, 而async是单独下载, 完成后立即执行.

怎样理解script标签的defer属性和async属性的更多相关文章

  1. HTML <script> 标签的 defer 和 async 属性

    HTMKL <script>标签中有defer和async属性,简单介绍一下两者的区别吧.   普通的script标签会让浏览器立即下载并执行完毕,执行也是按照先后顺序,再进行后面的解析. ...

  2. script标签的defer、async属性

    之前一直对script标签的defer.async属性一知半解,直到看到了论坛上某大神发的图片,茅塞顿开!!!!!

  3. script标签中defer和async属性的区别

    这篇文章来源于JS高级程序设计第三版中关于script标签的介绍,结合查阅的资料写下的学习笔记. 向html页面中插入javascript代码的主要方法就是通过script标签.其中包括两种形式,第一 ...

  4. script 标签的defer,async的作用,及拓展浏览器多线程,DOMContentLoaded

    前端优化有一点就是优化js的执行时机,一般做法是将script放置于body的结束标签,以避免加载执行js 文件导致页面渲染阻塞的问题这种做法确实能防止页面阻塞,但是在页面渲染完成之后才去加载js文件 ...

  5. 【JavaScript性能优化】------理解Script标签的加载和执行

    1.script标签是如何加载的?当浏览器遇到一个 < script>标签时,浏览器会停下来,运行JavaScript代码,然后再继续解析.翻译页面.同样的事情发生在使用 src 属性加载 ...

  6. HTML中<script>的defer属性与async属性

    defer 属性会在 DOMLoaded 事件之前完成异步加载,加载不会阻塞 DOM 解析,并且 script 的顺序会按照 DOM 中的顺序加载. async 属性就是异步加载,没有什么顺序的保证.

  7. script标签中defer和async的区别(稀土掘金学习)

    如果没有defer或async属性,浏览器会立即加载并执行相应的脚本.它不会等待后续加载的文档元素,读取到就会开始加载和执行,这样就阻塞了后续文档的加载. 下图可以直观的看出三者之间的区别: 其中蓝色 ...

  8. 您是不是奇怪为什么 <script> 标签中没有 type="text/javascript" 属性?

    在 HTML5 中该属性不是必需的.JavaScript 是 HTML5 以及所有现代浏览器中的默认脚本语言!

  9. Javascript高级编程学习笔记(2)—— Script标签

    script标签 js在浏览器中的使用,肯定会涉及到script标签. 那么script标签有哪些属性呢? 1.async:异步加载(不让页面等待该脚本的加载执行,异步加载页面的其他部分) 2.cha ...

随机推荐

  1. AWS 配置IPv6

  2. LeetCode 快乐数(Happy Number)

    题目描述 编写一个算法来判断一个数是不是“快乐数”. 一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不 ...

  3. 定时杀死warn进程

    6 6 * * * /root/wz/mysqlRestart.sh    #MySQL restart7 6 * * * /bin/sh /home/warn/kill_.sh8 6 * * * / ...

  4. selenium chromedriver与chrome版本对应表

    chromedriver版本   支持的Chrome版本 v2.41               v67-69 v2.40               v66-68 v2.39             ...

  5. 动态绑定easyui datagrid列名

    根据实时数据在同一个DataGrid中显示不同字段,本身easyui并没有支持动态绑定列名,只有show属性显示或隐藏某字段.今天在网上看到直接修改easyui类库动态绑定列名的方法,废话不多说直接借 ...

  6. iOS面试经历(个人)

    1.OC的runtime运行机制1> runtime,运行时机制,它是一套C语言库2> 实际上我们编写的所有OC代码,最终都是转成了runtime库的东西,比如类转成了runtime库里面 ...

  7. 安装android sdk,后出现导出错误,提示命令行找不到解决方案

    The steps. Rename android sdk tool folder : [Your Android SDK root]/tools -> toolsXXXX Download S ...

  8. Object.defineProperty()方法学习笔记

    这是js中一个非常重要的方法,ES6中某些方法的实现依赖于它,VUE通过它实现双向绑定 此方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象 参数 Object.def ...

  9. Arduino图形化编程软件ArduBlock的安装过程

    ArduBlock是一款图形编程插件,接下来我们在Windows10上进行安装 注意ArduBlock虽然能安装在1.83版本的Ardunio上,但在载入程序时会报错,用本身的IDE不会出现这种情况. ...

  10. 【C/C++开发】运算符重载二

    C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类 ...