async-vs-defer

asyncdefer都是用来延迟(异步)加载脚本,但两者之间还是存在一些区别的,因此使用场景也有所不同。

Legend

legend

script

script标签不带asyncdefer特性时。当浏览器解析HTML遇到该script标签时,会暂停解析工作。然后会发起脚本请求,在脚本下载完便开始执行,只有在脚本执行完之后才恢复HTML解析。

script

script with async

script标签带async特性时。当浏览器解析HTML遇到该script标签时,此时脚本的下载不会阻塞HTML的解析,只有在脚本下载完开始执行时,才会阻塞HTML的解析。async可以不能保证脚本执行顺序(在文档中出现的顺序),因为执行顺序取决于下载完的顺序。

script

script with defer

script标签带defer特性时。当浏览器解析HTML遇到该script标签时,此时脚本的下载不会阻塞HTML的解析,脚本只有在HTML解析完之后才开始执行。defer可以保证脚本执行顺序(在文档中出现的顺序)。

script

对比

  • 相同之处:

    • 在脚本下载时,都不会阻塞文档解析
    • 支持onload事件回调处理,用于一些初始化工作
    • 对内联脚本无效
    • 脚本中不能调用document.write()
  • 不同之处:

    带有async特性的脚本会在脚本下载完后立即执行,且在load事件之前,所以不能确保脚本在文档中出现的顺序来执行。而带有defer特性的脚本会在文档解析完后按照在文档出现的顺序依次执行,且在DOMContentLoaded事件之前。

使用规则

一般尽可能使用async,然后考虑defer,最后不使用任何特性

  • 如果脚本是一个模块并且没有依赖于其他脚本时,使用async
  • 如果脚本依赖于其他脚本或被其他脚本依赖时,使用defer
  • 如果脚本较小,并且被其他带async的脚本依赖,可以将该脚本直接内联script标签中,并放置在async脚本之前



兼容

在<=IE9浏览器对defer的实现存在一些bug,如defer不能保证script的执行顺序,如果需要支持<=IE9,不建议使用defer,如果scirpts的执行顺序重要,可以不设置任何特性,了解更多

参考文章:


声明:本资料仅供学习交流,严禁使用于任何商业用途! 如需转载,转载请注明出处。