怎样理解script标签的defer属性和async属性
如果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是单独下载, 完成后立即执行.
原文地址:https://www.cnblogs.com/aisowe/p/11698983.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 十个问题弄清JVM&GC(一)
- 蜂鸟E203系列——按键中断设计
- 蜂鸟E203系列—— UART 设计
- iOS逆向开发(7):微信伪装他人
- 因为喜欢所以升级,MyStaging-3.0 继续
- 环境与工具篇:建立高效的macos环境
- 0202年你还不知道面向对象?
- 十问泛型,你能扛住吗?
- 【两万字】面试官:听说你精通集合源码,接我二十个问题!
- 手把手教你搭建一个技术人的博客
- 发布更新|腾讯云 Serverless 产品动态 20200723
- Spring中异步注解@Async的使用、原理及使用时可能导致的问题
- Elasticsearch 聚合数据结果不精确,怎么破?
- Elasticsearch 预处理没有奇技淫巧,请先用好这一招!
- 时滞微分方程的matlab解法