<script>元素的async和defer属性支持度已经不错了,是时候详细了解它们了。
图例
<script>
<script>脚本不设置任何属性。HTML文档解析过程中,遇到script文档时,会停止解析HTML文档,发送请求获取script文档(如果是外部文档的话)。脚本执行后,才恢复HTMl文档解析。
<script async>
设置async属性后,在HTML解析的同时,下载script文档。script文档下载完成后,HTMl解析会暂停,来执行script文档。
<script defer>
设置defer属性后,在HTML解析的同时,下载script脚本。但只有在HTML解析完成后,才执行script文档。同时,defer属性保证脚本按照其在文档中出现的顺序执行。
如何选用?
通常情况下,尽可能的使用async属性,然后考虑defer,都不适用时才不设置任何属性。选用规则:
- 如果脚本是模块化的,并且不依赖其他脚本,那么使用async。
- 如果脚本依赖其他脚本或被其他脚本依赖,那么使用defer。
- 如果脚本比较小,并且被一个async脚本依赖,那么使用行内脚本,并放置在async脚本之前。
支持情况
IE9及以下浏览器在实现defer属性上存在糟糕的bug,比如无法保证脚本的执行顺序。如果需要支持<=IE9,不建议使用defer,如果执行顺序非常重要的话,不要使用任何属性。查看规范
后记
Chrome为了更快的页面加载,引入了两项JavaScript新技术:script streaming 和 code caching。简而言之,前者优化脚本文档的解析(Chrome 41),后者缓存编译后的代码(Chrome 42)。