async和defer属性的区别-[译]

原文:https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
目前script标签的async和defer属性已经得到不错的支持,所以是时候更详细的了解他们的具体的工作了。

图例说明

legend

纯script

首先我们来看没有定义任何属性的script标签。 HTML文件将被解析,直到脚本文件被点击为止,同时将停止解析,发起请求去提取script文件(如果是外部文件)。下载完成后将在恢复解析之前执行该脚本。
执行图

设置async的script

设置async属性会在HTML解析期间下载script文件,并在完成下载后暂停HTML解析器以执行该文件。
执行图

设置defer的script

设置defer属性会在HTML解析完成之后下载script,并在下载完成后执行该文件,同时设置了defer的脚本会按照他们在文档里面出现的顺序执行。
执行图

我们应该用哪一个?

通常我们会尽可能使用async,然后是延迟属性defer,其次才是不使用。以下是一般使用规则:

  • 如果脚本文件是独立的模块化的,且不依赖其他的脚本文件时用async;
  • 如果该脚本依赖于另一个脚本或被另一个脚本依赖,则使用defer;
  • 如果该脚本很小,并且由异步脚本所依赖,则请使用一个内联脚本,该脚本应在异步脚本上方不放置任何属性。

兼容

IE9及更低版本的defer实施中存在一些非常糟糕的错误,因此无法保证执行顺序。如果您需要兼容 <= IE9,我建议完全不要使用defer,并且如果执行顺序很重要,则使用未设置属性的script。