浅谈JavaScript中的defer,async
引言
开始重读<<JavaScript高级程序设计>>一书,看到关于JavaScript中关于defer、async的部分。网上查询了点资料,觉得蛮好的。现在总结下。
defer/async(Html5新增)
首先我们来看一下在<script>标签中如何使用这两个属,如下:
<script type="text/javascript" defer="defer" async="true/false" src="js文档地址"></script>
下面我们一个一个来看,看看这两个属性的设置对于JavaScript文件加载和执行的影响。
1、<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。
2、<script async src="script.js"></script>
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。
3、<script defer src="myscript.js"></script>
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
然后从实用角度来说呢,首先把所有脚本都丢到 </body> 之前是最佳实践,因为对于旧浏览器来说这是唯一的优化选择,此法可保证非脚本的其他一切元素能够以最快的速度得到加载和解析。
下面我们通过一张形象的图来更加直观的解释这两个属性。

蓝色线代表网络读取,红色线代表执行时间,这俩都是针对脚本的;绿色线代表 HTML 解析。
此图告诉我们以下几个要点:
- defer 和 async 在网络读取(下载)这块儿是一样的,都是异步的(相较于 HTML 解析)
- 它俩的差别在于脚本下载完之后何时执行,显然 defer 是最接近我们对于应用脚本加载和执行的要求的
- 关于 defer,此图未尽之处在于它是按照加载顺序执行脚本的,这一点要善加利用
- async 则是一个乱序执行的主,反正对它来说脚本的加载和执行是紧紧挨着的,所以不管你声明的顺序如何,只要它加载完了就会立刻执行
- 仔细想想,async 对于应用脚本的用处不大,因为它完全不考虑依赖(哪怕是最低级的顺序执行),不过它对于那些可以不依赖任何脚本或不被任何脚本依赖的脚本来说却是非常合适的,最典型的例子:Google Analytics
defer和async的比较
相同点:
- 加载文件时不阻塞页面渲染;
- 对于inline的script无效;
- 使用这两个属性的脚本中不能调用document.write方法;
- 有脚本的onload的事件回调;
- 允许不定义属性值,仅仅使用属性名;
不同点:
- html的版本html4.0中定义了defer;html5.0中定义了async;这将造成由于浏览器版本的不同而对其支持的程度不同;
- 执行时刻:每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。
这两个属性会有三种可能的组合:
- 如果async为true,那么脚本在下载完成后异步执行。
- 如果async为false,defer为true,那么脚本会在页面解析完毕之后执行。
- 如果async和defer都为false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行。
浅谈JavaScript中的defer,async的更多相关文章
- 浅谈JavaScript中的闭包
浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...
- 浅谈JavaScript中的null和undefined
浅谈JavaScript中的null和undefined null null是JavaScript中的关键字,表示一个特殊值,常用来描述"空值". 对null进行typeof类型运 ...
- 浅谈JavaScript中的正则表达式(适用初学者观看)
浅谈JavaScript中的正则表达式 1.什么是正则表达式(RegExp)? 官方定义: 正则表达式是一种特殊的字符串模式,用于匹配一组字符串,就好比用模具做产品,而正则就是这个模具,定义一种规则去 ...
- 浅谈JavaScript中的内存管理
一门语言的内存存储方式是我们学习他必须要了解的,接下来让我浅谈一下自己对他的认识. 首先说,JavaScript中的变量包含两种两种类型: 1)值类型或基本类型:undefined.null.numb ...
- 浅谈JavaScript中闭包
引言 闭包可以说是JavaScript中最有特色的一个地方,很好的理解闭包是更深层次的学习JavaScript的基础.这篇文章我们就来简单的谈下JavaScript下的闭包. 闭包是什么? 闭包是什么 ...
- 浅谈JavaScript中的继承
引言 在JavaScript中,实现继承的主要方式是通过原型链技术.这一篇文章我们就通过介绍JavaScript中实现继承的几种方式来慢慢领会JavaScript中继承实现的点点滴滴. 原型链介绍 原 ...
- 浅谈JavaScript中继承的实现
谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我 ...
- 【总结】浅谈JavaScript中的接口
一.什么是接口 接口是面向对象JavaScript程序员的工具箱中最有用的工具之一.在设计模式中提出的可重用的面向对象设计的原则之一就是“针对接口编程而不是实现编程”,即我们所说的面向接口编程,这个概 ...
- 通过一道笔试题浅谈javascript中的promise对象
因为前几天做了一个promise对象捕获错误的面试题目,所以这几天又重温了一下promise对象.现在借这道题来分享下一些很基础的知识点. 下面是一个面试题目,三个promise对象捕获错误的例子,返 ...
随机推荐
- Mysql主从复制,读写分离(mysql-proxy),双主结构完整构建过程
下面介绍MySQL主从复制,读写分离,双主结构完整构建过程,不涉及过多理论,只有实验和配置的过程. Mysql主从复制(转载请注明出处,博文地址:) 原理是master将改变记录到二进制日志(bina ...
- JAVA JVM虚拟机选项:Xms Xmx PermSize MaxPermSize 区别
Xms : 是指设定程序启动时占用内存大小.一般该值设置大的会使程序启动快,但是可能会使本机暂时变慢. Xmx : 是指设定程序运行期间最大可占用的内存大小,如果程序运行需要占用更多的内存,超出这个 ...
- 安卓直播开源: RTMP 推流SDK
前些日子在github上提交了基于GPUImage的IOS直播推流SDK(https://github.com/runner365/GPUImageRtmpPush) 最近整理了android直播推流 ...
- spring mvc 快速入门
---------- 转自尚学堂 高淇 --------- Spring MVC 背景介绍 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块.使用 Spring 可插入的 MVC ...
- JS 阶段小练习~ 无缝滚动
结合下学了的知识,做个模拟的综合性扩展练习~~ 大致功能如下: 1.点开html后,图片自动移动展示 2.点击左右方向,可以改变 图片移动的方向(改变left的值,正负) 3.鼠标移入移出图片后,图 ...
- 【读书笔记《Bootstrap 实战》】4.企业网站
上一章有对个人作品站点进行一些优化.本章,轮到我们充实这个作品站点了,补充一些项目,从而展示我们的能力.换句话说,我们要构建一个相对复杂的企业网站主页. 下面有几个成功企业的网站: □ Zappos ...
- Java并发编程实例(synchronized)
此处用一个小程序来说明一下,逻辑是一个计数器(int i):主要的逻辑功能是,如果同步监视了资源i,则不输出i的值,但如果没有添加关键字synchronized,因为是两个线程并发执行,所以会输出i的 ...
- 第1章 重构,第一个案例(2):分解并重组statement函数
2. 分解并重组statement (1)提炼switch语句到独立函数(amountFor)和注意事项. ①先找出函数内的局部变量和参数:each和thisAmount,前者在switch语句内未被 ...
- kettle运行spoon.bat时找不到javaw文件
我也遇到这问题了,分享一下解决方法吧以后没准还有人能用到.我机器的主要问题是环境变量JAVA_HOME的值不对,应该写到jdk也就是C:\Program Files\Java\jdk1.7.0_25, ...
- JS数组去重比较
数组去重复是一个常见的需求,我们暂时考虑同类型的数组去重复.主要是理清思路和考虑执行性能. for循环删除后面重复的 var uniqueFor = function(arr) { for (var ...