如果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. mysql 实现同一个sql查询 分页数据 和总记录数

    $get_sql = "SELECT sql_calc_found_rows field1,field2 FROM table WHERE name = '1' order by add_t ...

  2. 【DOS】取某目录下某类型文件信息放入文本

    C:\Users\horn1\Desktop\新建文件夹>dir *.jar >1.txt 这样,所有扩展名为jar的文件信息就送到新建的文本文件1.txt中了.虽然简单,但也是个常用功能 ...

  3. A filter or servlet of the current chain does not support asynchronous operations. 错误解决记录

    做视频文件上传一直报这个错误: java.lang.IllegalStateException: A filter or servlet of the current chain does not s ...

  4. JS-数组与伪数组

    数组与伪数组 把符合以下条件的对象称为伪数组: 具有length属性 按索引方式存储数据 不具有数组的push,pop等方法 伪数组(类数组):无法直接调用数组方法或期望length属性有什么特殊的行 ...

  5. SQL-W3School-函数:SQL AVG() 函数

    ylbtech-SQL-W3School-函数:SQL AVG() 函数 1.返回顶部 1. 定义和用法 AVG 函数返回数值列的平均值.NULL 值不包括在计算中. SQL AVG() 语法 SEL ...

  6. AndroidStudio制作Nine-Patch【.9】图片

    使用AndroidStudio制作Nine-Patch[.9]图片,以及为什么要制作Nine-Patch[.9]图片[以聊天气泡为例]   本文链接:https://blog.csdn.net/She ...

  7. 关于define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -7));的理解

    关于define('DISCUZ_ROOT', substr(dirname(__FILE__), 0, -7));的理解 define('DISCUZ_ROOT',  substr(dirname( ...

  8. ARM程序的RO段、RW段和ZI段 --Image

    Limit 含义了解RO,RW和ZI需要首先了解以下知识:ARM程序的组成此处所说的“ARM程序”是指在ARM系统中正在执行的程序,而非保存在ROM中的bin映像(image)文件,这一点清注意区别. ...

  9. Oracle客户端下载地址

    https://www.oracle.com/database/technologies/instant-client/downloads.html

  10. 【Leetcode_easy】709. To Lower Case

    problem 709. To Lower Case solution1: class Solution { public: string toLowerCase(string str) { stri ...