defer 和 async 是 script 中控制脚本加载和执行的两个属性:
defer和async 都是 HTML5 中引入的特性,早期浏览器可能不支持。通常情况下,现代浏览器都支持这两个属性
结果
defer,脚本异步加载,与html解析并行,下载完直接执行,可能会打断html解析。不保证脚本按照html中的顺序执行,有较好的兼容性。适用于页面解析完成后,dom结构完整,多个脚本需要顺序执行的场景。
async,脚本异步加载,html解析完成后,DomContentLoaded事件触发之前按顺序执行,保证脚本可以按照html中的顺序执行。html5的新增属性,兼容性较差。适用于不依赖页面加载顺序的,对执行时间要求不高的场景。
如果脚本需要依赖 DOM 或其他脚本,并且需要按照特定顺序执行,请使用 defer。
如果脚本是独立运行的,且不需要依赖 DOM 或其他脚本,为了提高页面加载速度,可以使用 async。
对比
1、加载方式
-
defer:脚本文件会与 HTML 文件一起异步加载,但不会阻塞 HTML 的解析过程。这意味着浏览器在解析 HTML 的同时会下载脚本文件,但不会等待脚本下载完成后再继续解析 HTML。 -
async:脚本文件同样异步加载,但加载完成后会立即执行,不会等待 HTML 解析完成。因此,多个带有async属性的脚本可能会因为加载顺序不同而执行顺序不确定
2、执行时机
-
defer:脚本会在 HTML 解析完成后(即 DOM 完全构建后,但还在DOMContentLoaded事件触发之前)执行。如果页面中有多个带有defer属性的脚本,它们会按照在 HTML 中出现的顺序依次执行。 -
async:脚本会在加载完成后立即执行,不受 HTML 解析的影响。脚本的执行时机取决于加载完成的时间,而非 HTML 解析完成的时间。多个带有async属性的脚本之间没有固定的执行顺序。
3、 执行顺序
-
defer:保证脚本按照在 HTML 中出现的顺序依次执行。这使得defer更适合需要依赖其他脚本或依赖 DOM 的场景。 -
async:不保证脚本的执行顺序,加载完成的脚本会立即执行,因此多个async脚本可能会打乱原有的加载顺序
4、适用场景
-
defer:适用于需要依赖 DOM 或其他脚本的场景,例如统计代码、广告脚本等。这些脚本必须在 DOM 完全构建后才能正确运行。 -
async:适用于独立运行的脚本,例如第三方统计工具、广告代码、行为分析等。这些脚本不需要依赖 DOM 或其他脚本,可以加快页面加载速度