初了解:defer 和 async 用法及总结
一、首先了解一下浏览器的引擎类型
引自自学JavaScript 0330 课程
附录文章
公司 | 浏览器 | JS引擎 | 渲染引擎 |
---|---|---|---|
Microsoft | IE6-8 | JScritp | Trident |
IE9-11 | Chakra | Trident | |
Edge(2015年) | Chakra | Edge | |
Mozilla | Firefox | JagerMonkey | Gecko |
Chrome | V8 | 以前用的webkit,13年以后用的Blink | |
Apple | Safari | SquirrelFish | Extreme |
Opera | Opera12.16+ | Carakan | 13年以后用Blink |
在CSS3中,各个浏览器的私有属性前缀:
- moz代表firefox浏览器私有属性
- ms代表IE浏览器私有属性
- webkit代表chrome、safari私有属性
- o-表示opera
二、首先了解一下浏览器的引擎类型
1. defer
- 这个属性的用途是表明脚本在执行时不会影响页面的构造。也就是说,脚本会被延迟到整个页面都解析完毕后再运行。因此,在
<script>
元素中设置defer属性,相当于告诉浏览器立即下载,但延迟执行。 - HTML5规范要求脚本按照它们出现的先后顺序执行,因此第一个延迟脚本会先于第二个延迟脚本执行,而这两个脚本会先于
DOMContentLoaded
事件执行。在现实当中,延迟脚本并不一定会按照顺序执行,也不一定会在DOMContentLoad
时间触发前执行,因此最好只包含一个延迟脚本。
2. async
-
这个属性与defer类似,都用于改变处理脚本的行为。同样与defer类似,async只适用于外部脚本文件,并告诉浏览器立即下载文件。但与defer不同的是,标记为async的脚本并不保证按照它们的先后顺序执行。
-
第二个脚本文件可能会在第一个脚本文件之前执行。因此确保两者之间互不依赖非常重要。指定async属性的目的是不让页面等待两个脚本下载和执行,从而异步加载页面其他内容。
引用segmentfault上的一个回答中的一张图
蓝色线代表网络读取,红色线代表执行时间,这俩都是针对脚本的;绿色线代表 HTML 解析。
也就是说async是乱序的,而defer是顺序执行,这也就决定了async比较适用于百度分析或者谷歌分析这类不依赖其他脚本的库。从图中可以看到一个普通的<script>
标签的加载和解析都是同步的,会阻塞DOM的渲染,这也就是我们经常会把<script>
写在<body>
底部的原因之一,为了防止加载资源而导致的长时间的白屏,另一个原因是js可能会进行DOM操作,所以要在DOM全部渲染完后再执行。
三、结论
其实这么讲来,最稳妥的办法还是把<script>
写在<body>
底部,没有兼容性问题,没有白屏问题,没有执行顺序问题,高枕无忧,不要搞什么defer和async的花啦~