我理解它的方式,脚本应该是defer
ed而不是async
ed因为这样解析不需要停止执行它们(我将通过these graphs)。如果必须停止解析,这意味着页面内容需要更长时间才能显示正确吗?如果是这样的话,为什么async
会比defer
更好?
示例:我在我的网站上使用Google reCAPTCHA。 Google要求我在关闭</head>
代码之前插入脚本:
<script src='https://www.google.com/recaptcha/api.js'></script>
</head>
为什么在页面加载完成之前需要执行此脚本?我不应该defer
吗?
好吧,在网上搜了几个小时后,我终于得到了答案!来自this fantastic blog post:
加载ASYNC的脚本在资源下载时立即解析并执行。而在完成HTML文档解析之前,DEFER脚本不会执行(AKA,DOM Interactive或performance.timing.domInteractive)。
...
比较ASYNC和DEFER瀑布,我们发现使用DEFER可以更快地激活DOM Interactive,并允许渲染更快地进行。
然而:
即使ASYNC和DEFER不阻止HTML解析器,它们也可以阻止渲染。在渲染完成之前解析并执行它们并接管浏览器主线程时会发生这种情况。 spec中没有任何内容表明他们必须等到渲染完成。
所以基本上,我对此的理解是渲染(尽管it happens somewhat in parallel with parsing)使用defer
变得更快,但最终由于在整个渲染过程中执行所有javascripts,页面加载时间也一样长。这对用户来说稍微令人满意,因为他们可以更快地看到事物。但是,如果我们真的想提高装载速度,我们应该尽可能使用load scripts after onload。
总结:似乎没有任何理由使用async
而不是defer
。
是的async有时候比延迟更好,有时甚至是劣等。这可以通过计时轻松测试,直到您关心的事件发生在使用异步或延迟(或加载或按负载插入等)上。许多浏览器甚至都带有内置的开发人员工具来向您展示定时事件的“瀑布”。
你提到的图表在概念上非常有用,但它们并没有提供任何科学的测量。只测量您关心的事件的时间总是(统计上)准确地告诉您哪个是最快的。
你要么测试了一件事,要么仅依靠信仰。
(特别是谷歌reCAPTCHA,我不太了解它,但我确实知道在某些实现中它会通过各种可用标准尝试[就像鼠标光标在与显示的CAPTCHA交互之前一样移动]提前确定页面是否可能被实际人类使用。人类经常在页面完全加载之前经常与页面交互,所以这段时间会提供这方面的有用信息。也就是说,如果是脚本无论你的实现是什么,即使在某种程度上低于另一个实现,它都适用于你。如果你没有一种方法来确定成功的功能,那么你将永远迷失。)