最近看了javascript 高级程序设计第三版 和 高性能javascript 对于 延迟脚本好像有点出入(可能是我理解的出入,所以打算自己亲自测试一下 来证明 到底怎么回事)高级程序设计中对于defer的解释:这个属性的用途表明脚本在执行时不影响页面的构造 (脚本会被延迟到整个页面都解析完毕在运行)所以加上这个属性就是告诉浏览器在遇到这个属性的时候立即下载但是延迟去执行 html5规范如果有多个defer的外部脚本 那么按照出现的先后顺序来执行 所有支持html5 的浏览器都应该按照这个规则来执行 而且最重要的是defer 只适用与外部脚本 内嵌脚本只有ie4-ie7才支持
好了上代码 看一下到底是怎么回事 以代码为准
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>defer</title> <script src="js/defer.js" defer="defer"></script> <script src="js/defer1.js" defer="defer"></script> </head> <body> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <p>这是p标签</p> <script type="text/javascript"> alert(1); window.onload=function () { alert(2) } </script> </body> </html>
外部脚本咱们看一下 defer.js的代码
alert(3)
defer1.js的代码呢 继续看一下
alert(4);
和大家说一下执行的顺序 和测试环境
(1)环境 火狐 40.0.3版本
<1>顺序是 1 3 4 2
(2)测试环境是 ie 7 8 9
<2>顺序是 1 3 4 2
(3)测试环境是谷歌版本45.0.2454.93
<3>顺序是 1 3 4 2
总结: 经过不完全测试 出现的顺序都是一样的 从而可以得出来 以下结论
(1): 含有defer属性的外部脚本会按照出现的先后顺序依次执行
(2): 含有defer属性的外部脚本会在 DOMContentLoaded事件之前执行(DOMContentLoaded:当所有DOM解析完以后会触发这个事件 firefox特有 就相当于jq代码 $(function(){}))
(3): 带有defer的属性的脚本不会阻塞浏览器的其他进程 因此可以与那个的其他资源并行下载
理解以上知识需要知道的内容(补充浏览器的运行机制)
1、执行并渲染html的进程遇到<script>时,无法确定脚本是否会影响文档内容,故下载与执行脚本会阻塞文档的解析与渲染。
即脚本的执行在默认情况下是同步和阻塞的。
2、<script>标签的defer和async布尔属性(只需出现在标签里即可)
这两个属性都像在告诉browsers链接进来的脚本都不会使用document.write(),也不会生成文档内容,因此浏览器可以在下载脚本时继续解析和渲染文档。
// 出现顺序是 1 3 4 2 // 测试环境是 火狐 40.0.3 // 测试环境是 ie9 ie7 ie8 出现顺序和 火狐一样 // 总结 会在onload 之前进行 // 测试环境谷歌45 顺序是 1 3 4 2
说完了defer再说一下 这个async 属性 (异步加载 )
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>async</title> <script src="js/async.js" async></script> <script src="js/async1.js" async></script> </head> <body> <p>我是用来测试的</p> <p>我是用来测试的</p> <p>我是用来测试的</p> <p>我是用来测试的</p> <p>我是用来测试的</p> <p>我是用来测试的</p> <script type="text/javascript"> alert(1) window.onload=function () { alert(2); } </script> </body> </html>
js外部脚本 和以上的 defer一样 只不过是修改了一下 名字而已
看结果
// 出现顺序是 4 3 1 2 火狐40.0.3版本
// 出现顺序是 3 4 1 2 ie 9 ie8 ie7
// 谷歌 1 4 3 2
标记为async属性的脚本不会保证他们的执行顺序 但是有一点可以保证就是肯定会在dom加载完毕之前执行
最后说一句 他们都是异步加载 只不过执行时机不同,最后偷了一张图 来说明一下他们的区别和类似之处 来作为最后的压轴 和结尾