为什么jQuery.ready这么慢却被推荐

Why is jQuery.ready recommended when it’s so slow?

本文关键字:jQuery ready 为什么      更新时间:2023-09-26

我以前也问过类似的问题,但我从来没有明确表达过我的观点,或者至少我认为这是一个非常相关的问题,值得提出来,看看是否有人能给出一些有见地的想法。

在使用jQuery时,我们中的许多人在加载DOM时使用jQuery.ready函数来执行init。它已经成为使用jQuery向网页添加DOM操作程序的事实上的标准方式。一些浏览器本身就存在相关事件,但jQuery在其他浏览器(如某些IE版本)中对其进行了模拟。示例:

<head>
<script>
    var init = function() { alert('hello world'); };
    $.ready(init);
</script>

现在,我们所有的测试都表明,这个事件可能相当缓慢。它几乎没有window.onload那么慢,但在执行之前通常会延迟100毫秒左右。如果是FF,它可以长达200-300毫秒,尤其是在刷新时。

这是一些非常重要的毫秒,因为这是在进行任何DOM操作(例如隐藏下拉列表)之前显示初始布局的时间量。很多时候,布局"闪烁"主要是由使用缓慢的DOM就绪事件引起的,这迫使程序员使用CSS隐藏元素,并可能降低其可访问性。

现在,如果我们在关闭body标记之前将init函数放在脚本标记中,它的执行速度会更快,通常大约是一半的时间,但有时甚至更快:

<head>
<script>
    var init = function() { alert('hello world'); };
</script>
</head>
<body>
<!-- some HTML -->
<script>init();</script>
</body>

一个简单的测试页面来证明差异:http://jsbin.com/aqifon/10

我的意思是,我们谈论的并不是一些"优化警察"在使用有效选择器时所提倡的几乎不明显的差异。我们讨论的是在加载DOM操作时的一些主要延迟。在FF中尝试这个例子,domready有时会慢100倍以上(300ms vs 2ms)。

现在我的问题是:为什么建议使用jQuery.ready,而它显然比其他替代方案慢得多?与使用jQuery.ready相比,在关闭BODY之前调用init有什么缺点?可以说使用domReady更"安全",但在什么情况下它比其他选项更安全?(我在想document.write和延迟脚本之类的东西)我们在许多客户端网站上使用BODY方式已经近5年了,从未遇到任何问题。它只是快了很多。

我还想知道,既然关于jsPerf和每10000次执行优化选择器几毫秒的问题有很多模糊之处,为什么对此没有太多讨论?这基本上是用户面临的第一次延迟,而且在每次页面加载时分割50-100毫秒似乎相当简单。。。

首先指向要点:

不,在关闭<body>之前呼叫您init没有任何缺点正如您所注意到的,它将比依赖$.ready()表现得更好,并且也将完美地与所有浏览器配合使用(甚至在IE上)。

然而,现在有理由使用$.ready(),在您的情况下,它们可能不适用:

  1. $.ready()使开发人员可以很容易地按照正确的顺序进行操作。特别是,关键是不要引用尚未加载的DOM元素。虽然这很简单,但许多开发人员仍然感到困惑。$.ready()是一个无需思考的问题,尽管速度很慢
  2. 在您已经说过的几个需要init()的脚本中,在您的身体末端手动这样做并不一定容易/方便。它需要对这些脚本的作用进行规范和了解。特别是,在依赖jQuery的库中,您经常会看到$.ready(),因为无论开发人员使用何种方式加载库,它都能使事情正常工作
  3. 随着异步模块定义(例如require.js)作为加载javascript的一种方式越来越流行,<body/>方法的结束并不能得到保证

一个优点是,您可以将代码放在页面中的任何位置。在我们的案例中,我们在CMS中使用了一个模板系统,它将不同部分的大约10-30个模板拼接在一起(取决于复杂性)。

由于您希望模板在使用的任何页面上都能工作,因此需要在其中包含必要的Javascript。对于这些情况,ready()函数是一个真正的救命稻草。

如果你写了一个JS文件,其他人也将其包含在页面中,那么在该文件中使用document.ready会更安全(假设DOM准备好后需要自动进行一些处理),因为你无法确定该文件是包含在头中还是包含在正文末尾。

当涉及到你可以完全控制的页面时,显然你不必担心,所以我认为使用document.ready比从正文末尾调用init()更"安全"。使用document.ready(或onload)和将脚本放在正文末尾是两种最常见的方法,它们很常见,因为它们都能很好地工作。

您提到document.write()可能是一个例外,但您不想从document.ready或正文末尾调用它,因为无论哪种方式,整个页面都已经被解析。

因为它使domReady和window.load变慢。

很容易根据指标进行优化,而不是根据实际用户体验进行优化。因此,"真正的用户优化"图会下降,即使交互性会延迟。

相关文章: