1.defer属性 延迟脚本
<html>
<head>
<title>哈哈</title>
<script type="text/javascript" defer="defer" src="example1.js"></script>
<script type="text/javascript" defer="defer" src="example2.js"></script>
</head>
<body>
</body>
</html>
例子中,虽然我们把< script>元素放在了文档的< head>元素中,但其中包含的脚本文件将延迟到浏览器遇到< html>标签后才执行,HTML5规范要求脚本按照他们出现的先后顺序只执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于DOMContenloaded事件执行。
2.async 异步脚本
该属性与defer属性类似,都用来改变处理脚本的行为,同样与defer类似,ansync只适合外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不按照指定他们的先后顺序执行。例如:
<html>
<head>
<title> 哈哈哈</title>
<script type="text/javascript" async="async" src="example1.js"></script>
<script type="text/javascript" async="async" src="example2.js"></script>
</head>
<body>
</body>
</html>
在以上的代码中,第二个脚本文件可能会在第一个脚本文件之前执行,因此为了确保两者之间不相互依赖非常重要,指定的async属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他的内容。为此,建议异步脚本不要在加载期间修改DOM。
异步脚本一定会在页面的load事件齐前执行,但可能会在 DOMContenloaded事件触发之前或之后执行。
二者区别分析
绿色线条为HTML解析;蓝色线条为异步脚本的下载;红色线条为异步脚本的执行时间
-
在没有设置defer或async属性的< script>脚本上,解析器在解析HTML代码时,遇到< script>标签就会暂停解析,将控制权交给js引擎,去下载js代码,下载完成后立即执行。执行完毕之后再继续解析HTML代码。
-
在遇到设置有defer属性的< script>标签时,解析器不会停止解析HTML代码,而是去另外开启一个线程下载延迟脚本;在HTML文档解析完成后,才开始执行该脚本。
-
在遇到设置有async属性的< script>标签时,解析器同样不会停止解析HTML代码,而是另外开启一个线程去下载异步脚本;但是不论HTML文档是否解析完毕,只要异步脚本加载完毕就会立即执行此处代码。