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 · 11 comments
Open

彻底搞懂 async & defer #8

xiaoyu2er opened this issue Mar 12, 2017 · 11 comments

Comments

@xiaoyu2er
Copy link
Owner

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
Copy link

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

@quanru
Copy link

quanru commented May 20, 2018

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

@xiaoyu2er
Copy link
Owner Author

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

@quanru
Copy link

quanru commented May 21, 2018

@xiaoyu2er 受教了~

@zhenmang
Copy link

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

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

@icantunderstand
Copy link

赞 多谢分享

@beinimaliesi
Copy link

<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
Copy link

jparser commented Feb 12, 2019

async会阻止DOM parase

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

@Archao-ME
Copy link

Defer 会阻止DOM parase

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

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

@zhixinpeng
Copy link

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

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

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

@ibufu
Copy link

ibufu commented Jul 23, 2020

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
Development

No branches or pull requests

10 participants