Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

彻底搞懂 async & defer #8

Open
xiaoyu2er opened this issue Mar 12, 2017 · 10 comments
Labels

Comments

@xiaoyu2er
Copy link
Owner

@xiaoyu2er xiaoyu2er commented Mar 12, 2017

彻底搞懂 async & defer

TL;DR

两者都会并行下载,不会影响页面的解析。

defer 会按照顺序在 DOMContentLoaded 前按照页面出现顺序依次执行。

async 则是下载完立即执行。

兼容性

普通 script

先来看一个普通的 script 标签。

<script src="a.js"></script>

浏览器会做如下处理

  • 停止解析 document.
  • 请求 a.js
  • 执行 a.js 中的脚本
  • 继续解析 document

defer

<script src="d.js" defer></script>
<script src="e.js" defer></script>
  • 不阻止解析 document, 并行下载 d.js, e.js
  • 即使下载完 d.js, e.js 仍继续解析 document
  • 按照页面中出现的顺序,在其他同步脚本执行后,DOMContentLoaded 事件前 依次执行 d.js, e.js。

async

<script src="b.js" async></script>
<script src="c.js" async></script>
  • 不阻止解析 document, 并行下载 b.js, c.js
  • 当脚本下载完后立即执行。(两者执行顺序不确定,执行阶段不确定,可能在 DOMContentLoaded 事件前或者后 )

其他

  • 如果 script 无 src 属性,则 defer, async 会被忽略
  • 动态添加的 script 标签隐含 async 属性。

结论

  • 两者都不会阻止 document 的解析
  • defer 会在 DOMContentLoaded 前依次执行 (可以利用这两点哦!)
  • async 则是下载完立即执行,不一定是在 DOMContentLoaded 前
  • async 因为顺序无关,所以很适合像 Google Analytics 这样的无依赖脚本

Reference

@Thinking80s

This comment has been minimized.

Copy link

@Thinking80s Thinking80s commented Mar 18, 2017

两者都不会阻止 document 的解析
defer 会在 DOMContentLoaded 前依次执行 (可以利用这两点哦!)
async 则是下载完立即执行,不一定是在 DOMContentLoaded 前
async 因为顺序无关,所以很适合像 Google Analytics 这样的无依赖脚本

@quanru

This comment has been minimized.

Copy link

@quanru quanru commented May 20, 2018

那是否认为 defer 可以替代普通的 script 标签?

@xiaoyu2er

This comment has been minimized.

Copy link
Owner Author

@xiaoyu2er xiaoyu2er commented May 21, 2018

@quanru 不可以啊
因为有可能 js 会修改 dom 啊

@quanru

This comment has been minimized.

Copy link

@quanru quanru commented May 21, 2018

@xiaoyu2er 受教了~

@zhenmang

This comment has been minimized.

Copy link

@zhenmang zhenmang commented Sep 23, 2018

@quanru 不可以啊
因为有可能 js 会修改 dom 啊

普通script标签内有js,带defer的script标签内也有js,都有可能修改DOM。在修改dom这点上,怎么论证“defer不能替代普通的script标签”呢?

@icantunderstand

This comment has been minimized.

Copy link

@icantunderstand icantunderstand commented Oct 25, 2018

赞 多谢分享

@tuxianchao

This comment has been minimized.

Copy link

@tuxianchao tuxianchao commented Jan 24, 2019

<script src="script.js"></script>

没有 defer 或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。

<script async src="script.js"></script>

有 async,加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行(异步)。

<script defer src="myscript.js"></script>

有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。

@jparser

This comment has been minimized.

Copy link

@jparser jparser commented Feb 12, 2019

async会阻止DOM parase

https://i.stack.imgur.com/wfL82.png

@Archao-ME

This comment has been minimized.

Copy link

@Archao-ME Archao-ME commented Mar 7, 2019

Defer 会阻止DOM parase

https://i.stack.imgur.com/wfL82.png

你这图是async运行时会HTML parsing paused,defer不会

@zhixinpeng

This comment has been minimized.

Copy link

@zhixinpeng zhixinpeng commented Sep 24, 2019

Defer 会阻止DOM parase
https://i.stack.imgur.com/wfL82.png

你这图是async运行时会HTML parsing paused,defer不会

他本来说的就是async会阻塞HTML解析,可作者说的是两者都不会阻塞HTML解析,明显是错误的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
9 participants
You can’t perform that action at this time.