在这篇文章中:
Why google is using the term "Render-Blocking JavaScript"?
@ jaffa-the-cake正在向某人发表评论:
“你认为哪一份文件不正确?”
我们以此文档为例:
https://developers.google.com/speed/docs/insights/BlockingJS
现在让我们以他们所说的“推迟”为例:
初始页面渲染不需要的脚本的加载和执行可以推迟到初始渲染或页面的其他关键部分完成加载之后。这样做有助于减少资源争用并提高性能。
请注意,该文章是关于“删除渲染阻止JavaScript”,因此使用“可能”一词意味着您可以使用延迟。
通过脚本标记上的“延迟”,您不会将“执行推迟到页面的初始渲染完成加载之后”。可能是这种情况,但不一定如此。
“Defer”将推迟执行,直到最初的html在DOM中,但这与“render”不同。执行将在(前面)html在DOM之后和DOMContentLoaded之前进行,但这并不意味着:“页面的渲染已经完成加载”。如果他们使用术语“页面的html解析已完成”将是正确的。
证实上述理论的一个例子:
INDEX.HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
</head>
<body>
Some HTML line and this is above the fold
<script src="script.js" defer></script>
</body>
</html>
SCRIPT.JS(来自缓存!)
// Synchronous delay of 5 seconds
var timeWhile = new Date().getTime();
while( new Date().getTime() - timeWhile < 5000 );
如果浏览器将从缓存中获取script.js,那么“一些HTML行,这是在首页之上”将在5秒后显示!这意味着页面的初始渲染尚未完成加载(使用延迟时)。所以我认为这意味着文档不正确。
附:如果没有来自缓存的script.js,浏览器将有时间完成前面的html渲染。首先必须下载文件script.js,这样才能给浏览器额外的时间。使用缓存,“完成解析html”和“javascript执行”之间的时间更短,因此在“完成前面的html渲染”之前,“javascript执行”有可能已经开始。因此,在速度增加的情况下,您甚至可以考虑在此示例中禁用缓存,因此前面的html的渲染将更快。
我有更多的测试/示例证明Google的其他文档(关于渲染)中的其他部分是不正确的(在我看来),但我将通过使用1个示例在本文中明确说明。
如果您不同意我的意见,请不要只给出负面的声誉,但至少要评论为什么您认为它不正确以及您做了哪些测试来确认。我已经试图说服谷歌的一些人在我看来他们是不正确的,但他们有点冒犯了。当然,如果我没有在其中投入大量时间/精力/测试并且如果我非常肯定的话,我不会说它们是不正确的。到现在为止,他们对我说:“考虑到误解可能是你的”,所以我觉得自己就像一个小男孩在与一堵大墙“战斗”。对我来说,它不是一开始就是正确的,但我看到我周围有这么多人(他们已经在IT工作多年)与主题渲染斗争,我可以理解它,因为关于它的文档是非常的混乱。这也是我深入研究它的原因,因为它对我来说也太混乱了,所以我想更好地理解它。如果我错了,只要说服我,我就是第一个说我错的人。
重新阅读你的问题和链接的引用后,我看到你来自哪里,以及为什么这个引用可能会产生误导。作为参考,让我把下面的报价与标题包括在一起:
推迟加载JavaScript
初始页面渲染不需要的脚本的加载和执行可以推迟到初始渲染或页面的其他关键部分完成加载之后。这样做有助于减少资源争用并提高性能。
你已经理解了这一点,但我会将它链接到how defer
works的参考。
正如你所提到的,是的,在defer
中执行JavaScript并且通常总是渲染阻塞,而defer
不会阻止DOM解析器。
引用误导/混淆的原因是因为粗体部分:
初始页面渲染不需要的脚本的加载和执行可以推迟到初始渲染或页面的其他关键部分完成加载之后。这样做有助于减少资源争用并提高性能。
“初始页面渲染不必要的脚本的加载和执行可以推迟到初始渲染之后”。虽然不是一个不正确的声明,但是会产生误导,因为性能的提升实际上是由于解析器没有被阻止。
这可以使用official documentation on defer
清楚地显示出来
如您所述,更直接,更清晰的方式来描述这个:
初始页面呈现不需要的脚本的加载和执行可以推迟到初始解析或页面的其他关键部分完成加载之后。这样做有助于减少资源争用并提高性能。
这清楚地表明性能增益是由于解析器被推迟。它也更符合defer
规范描述它和defer
的适应性:
如果
async
属性不存在但存在defer
属性,则将在页面完成解析时并行获取经典脚本并进行评估。如果两个属性都不存在,则立即获取并评估脚本,阻止解析直到这些都完成。 (W3C)