[转]script之defer&async
html5中script的async属性
我兴奋于html5的原因之一是一些久久未能实现的特性现在可以真正运用于实际项目中了. 如我们使用placeholder效果蛮久了但是那需要javascript来实现. 目前firefox和chrome都是实现了script标签的async属性.这个新的属性能让我们以一种更 简单的方式防止浏览器阻塞,在这之前我们需要用一些javascript小窍门来解决这个问题.
async - html代码
<script async src="myscript.js" onload="myInit()"></script> |
就像我之前提到的,加个属性很容易.
defer - html代码
script标签也有个defer属性,目前所有浏览器都已实现, 在firefox和chrome的早期版本没有实现此属性,IE从一开始就支持此属性.
<script defer src="myscript.js" onload="myInit()"></script> |
async & defer - 它们的区别是什么
带有async或者defer的script都会立刻下载并不阻塞页面解析,而且都提供一个可选的onload事件处理, 在script下载完成后调用,用于做一些和此script相关的初始化工作.它们的不同之处在于script执行的 时机.带有async的script,一旦下载完成就开始执行(当然是在window的onload之前).这意味着这些script 可能不会按它们出现在页面中的顺序来执行,如果你的脚本互相依赖并和执行顺序相关,就有很大的可能出问题, 例如变量或者函数未定义之类的错误. 而对于带有defer的script,它们会确保按在页面中出现的顺序来执行,它们执行的时机是在页面解析完后,但在 DOMContentLoaded事件之前.(亲测下来确实如此,下面会给出我的测试用例和说明)
目前哪些浏览器支持defer和async
目前来看,最新版本的firefox和chrome(还有同样webkit内核的safari,本人机器上的版本是ff6,chrome15dev-m,IE9)都已支持这两个属性,也都支持script的load事件. IE的话对于defer是一直都支持的,async属性IE6~9都没有支持(IE10毫无疑问的会支持),onload是在IE9中新加入的属性.
--------------------下面来一些我对defer,async,onload的测试用例------------------------------
写了简单的四段脚本用于测试
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
/** script1 **/window.ns = {};window.ns.delay = function(n) { var start = Number(new Date()), wait = n * 1000; while(true) { var end = Number(new Date()); if(end-start >= wait) { break; } } console.log("take " + n + " seconds to execute");};console.log("create a namespace named ns");document.addEventListener("DOMContentLoaded", function() { console.log("oh yeah, Dom Ready!");}, false);window.addEventListener("load", function() { console.log("oh yeah, All Resources Loaded!");}, false); |
|
1
2
3
4
5
6
7
8
9
|
/** script2 **/if(window.ns) { window.ns.one = 'ONE'; console.log('window.ns.one:' + window.ns.one); window.ns.delay(2);} else { console.log('oops...');} |
|
1
2
3
4
5
6
7
8
9
|
/** script3 **/if(window.ns && window.ns.one) { window.ns.two = "TWO"; console.log('window.ns.two:' + window.ns.two); window.ns.delay(2);} else { console.log('oops...');} |
|
1
2
3
4
5
6
7
8
|
/** script4 **/if(window.ns && window.ns.two) { window.ns.three = "THREE"; console.log('window.ns.three:' + window.ns.three);} else { console.log('oops...');} |
用于测试的基本html页面
<!DOCTYPE htm><html><head> <meta charset="utf-8"> <title>test</title> <script type="text/javascript" src="script1.js"></script> <script type="text/javascript" src="script2.js"></script> <script type="text/javascript" src="script3.js"></script> <script type="text/javascript" src="script4.js"></script></head><body> width="200" height="200" alt="a big image of beauty"/></body></html> |
剩下的事情就是在script上加上defer和async进行测试
1.无defer和async属性
<script type="text/javascript" src="script1.js"></script><script type="text/javascript" src="script2.js"></script><script type="text/javascript" src="script3.js"></script><script type="text/javascript" src="script4.js"></script> |
我们先看资源加载瀑布图(firefox和chrome类似,IE9的有点奇怪):

看得出来image的下载被script的执行给阻塞了.
console输出如下:

2.都给上defer属性
<script type="text/javascript" src="script1.js" defer></script><script type="text/javascript" src="script2.js" defer></script><script type="text/javascript" src="script3.js" defer></script><script type="text/javascript" src="script4.js" defer></script> |
资源加载瀑布图:

看得出来所有资源进行了并行下载,没有阻塞img的情况
console输出和第1个测试的输出一致,IE9和chrome是如此,但是奇怪的是Firefox在这种情况下, 居然没有触发DOMContentLoaded事件,即输出少了Dom Ready!一行


3.部分给上defer属性
<script type="text/javascript" src="script1.js"></script><script type="text/javascript" src="script2.js" defer></script><script type="text/javascript" src="script3.js" ></script><script type="text/javascript" src="script4.js" defer></script> |
因为这里面4个script都是有执行顺序依赖的,所以如果defer属性不加选择的添加的话,就会出麻烦, 本例中,script1和script3就会先执行,script2和script4晚执行,就出现错误了
console输出如下:

4.都给上async属性
<script type="text/javascript" src="script1.js" async></script><script type="text/javascript" src="script2.js" async></script><script type="text/javascript" src="script3.js" async></script><script type="text/javascript" src="script4.js" async></script> |
IE9根本不支持这个,所以不用测试. Firefox和chrome都是第一次访问时,出现了异步执行的情况, 之后有缓存的话script的执行顺序貌似得到了维护.资源时间瀑布上 表现出的是预期的情况,即没有给其他资源的下载造成阻塞

Chrome中第一次访问,console输出如下,无论出错与否chrome和firefox的DOMContentLoaded均未未触发

5.部分给async属性
<script type="text/javascript" src="script1.js" async></script><script type="text/javascript" src="script2.js"></script><script type="text/javascript" src="script3.js"></script><script type="text/javascript" src="script4.js" async></script> |
这种情况的效果在chrome下比较明显,分析起来也很简单,4个script都是并行下载,但是如果script1和script4下完后立马执行, 很显然就破环了它们之间的依赖关系,可惜的是这种竞争的现象在Firefox中出现的概率比较低,可能跟firefox的缓存机制有关系
chrome的console输出如下:

关于script的onload属性会另外写一篇文章来记录.
最后,如果您有什么疑问或者发现文中有错误,欢迎指出,共同进步
来源:
http://www.cnblogs.com/AndyWithPassion/archive/2011/09/03/2165441.html
[转]script之defer&async的更多相关文章
- script的defer和async
我们常用的script标签,有两个和性能.js文件下载执行相关的属性:defer和async defer的含义[摘自https://developer.mozilla.org/En/HTML/Elem ...
- 转:script中的async和defer
script中的async和defer defer: This Boolean attribute is set to indicate to a browser that the script is ...
- script 有哪个属性可以让它不立即执行 defer,async
.async 和 defer 属性 http://blog.csdn.net/qq_34986769/article/details/52155871 1. defer 属性<script sr ...
- script 标签的defer,async的作用,及拓展浏览器多线程,DOMContentLoaded
前端优化有一点就是优化js的执行时机,一般做法是将script放置于body的结束标签,以避免加载执行js 文件导致页面渲染阻塞的问题这种做法确实能防止页面阻塞,但是在页面渲染完成之后才去加载js文件 ...
- 浅谈JavaScript中的defer,async
引言 开始重读<<JavaScript高级程序设计>>一书,看到关于JavaScript中关于defer.async的部分.网上查询了点资料,觉得蛮好的.现在总结下. defe ...
- 【javascript】script标签的async异步解析
<script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染 ...
- defer async 区别
链接 <script src="script.js"></script> 没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是 ...
- HTML中<script>的defer属性与async属性
defer 属性会在 DOMLoaded 事件之前完成异步加载,加载不会阻塞 DOM 解析,并且 script 的顺序会按照 DOM 中的顺序加载. async 属性就是异步加载,没有什么顺序的保证.
- <script> 的defer和async
<script src="../file.js" async="async"></script> file.js---- 仅仅只有ale ...
随机推荐
- ubuntu16.04 Cmake学习二
本节主要总结编译程序的时候使用了第三方库的情况,以调用开源opencv-2.4.9为例子,具体安装详见http://www.cnblogs.com/xsfmg/p/5900420.html. 工程文件 ...
- LinkedList 基本示例及源码解析
目录 一.JavaDoc 简介 二.LinkedList 继承接口和实现类介绍 三.LinkedList 基本方法介绍 四.LinkedList 基本方法使用 五.LinkedList 内部结构以及基 ...
- Spark源码分析之五:Task调度(一)
在前四篇博文中,我们分析了Job提交运行总流程的第一阶段Stage划分与提交,它又被细化为三个分阶段: 1.Job的调度模型与运行反馈: 2.Stage划分: 3.Stage提交:对应TaskSet的 ...
- oracle函数中lead,lag,over,partition by 的使用
lead,lag函数的分析 http://blog.csdn.net/mazongqiang/article/details/7621328 举例如下: SQL> select * from ...
- mybatis--foreach,choose 小结
写博客个人不喜欢写那种长篇大论.富有文採与哲学的文章,搞开发的就喜欢直击重点,仅仅记录重要的信息就好了,以后查看的时候也很方便! mybatis 中 在if语句或when中 假设推断一个字段是否和1同 ...
- 初识python轻量web框架flask
1.使用pip安装Python包 大多数Python包都使用pip实用工具安装,使用pyvenv创建的虚拟环境会自动安装pip. 1.使用pip安装Flask(其它Python包同理) pip ins ...
- WCF基础之配置服务
在WCF应用编程中配置服务是其主要部分. 配置可以定义和自定义如何向客户端公开服务,包括服务地址,发送和接受消息的传输和编码,以及服务的安全类型. 服务的配置有两种:编码和使用config文件,大多数 ...
- PPID=1 runs as a background process, rather than being under the direct control of an interactive user
https://en.wikipedia.org/wiki/Daemon_(computing) [后台进程,非互动] d 结尾 syslogd 系统日志记录 sshd 响应ssh连接请求 In mu ...
- SPFA的两个优化:SLF与LLL
先举出个例题:洛谷P3371 [模板]单源最短路径 一眼扫去:最短路径. spfa不接受反驳... 附上代码: #include<iostream> #include<algorit ...
- TCP/IP协议之ARP寻址
ARP协议: 前面讲了网络层的寻址是通过IP地址来做的.其实一个数据包寻址包含两个部分:1 IP寻址.2 ARP寻址. ARP寻址是用在数据链路层上的.我们上网的电脑都有网卡.那么在数据链路层的进行传 ...