异步脚本、延迟脚本与DOMContentLoaded的关系

Table of Contents

sync

如上图所示, HTML 文档被解析时如果遇见(同步)脚本,则停止解析,先去加载脚本,然后执行,执行结束后继续解析 HTML 文档。HTML文档解析完毕后触发DOMContentLoaded。

async

分为两种情况:异步脚本先执行完,dom先解析完或dom和异步脚本同时完成

异步脚本先执行完

HTML 还没有被解析完的时候,async脚本已经加载完了,那么 HTML 停止解析,去执行脚本,脚本执行完毕后触发DOMContentLoaded事件。

dom先解析完或dom和异步脚本同时完成

HTML 解析完了之后,async脚本才加载完,然后再执行脚本,那么在HTML解析完毕、async脚本还没加载完的时候就触发DOMContentLoaded事件。

总结

DomContentLoaded 事件只关注 HTML 是否被解析完,而不关注 async 和sync脚本。

defer

defer与上面的同步和异步脚本不同,defer执行脚本的阶段必须在dom解析完毕之后。它也分为两种情况:defer先加载完和dom先解析完

defer先加载完

HTML还没解析完成时,defer脚本已经加载完毕,那么defer脚本将等待HTML解析完成后再执行。defer脚本执行完毕后触发DOMContentLoaded事件。

dom先解析完

HTML解析完成时,defer脚本还没加载完毕,那么defer脚本继续加载,加载完成后直接执行,执行完毕后触发domContentLoaded事件。

总结

如果在dom解析完成以后,defer脚本没有执行,在dom解析完成后,defer会率先被执行,会延迟domContentLoaded事件的触发。