32

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

在使用 jQuery 时,我们中的许多人使用该jQuery.ready函数init在 DOM 加载时执行。它已成为使用 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 倍以上(300 毫秒对 2 毫秒)。

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

我也想知道,既然关于 jsPerf 和每 10000 次执行几毫秒优化选择器的问题太多了,为什么没有太多谈论这个?这基本上是用户面临的第一个延迟,并且在每个页面加载时切片 50-100 毫秒似乎相当简单......

4

4 回答 4

8

先说重点:

不,init在关闭<body>. 正如您所注意到的,它会比依赖于$.ready()所有浏览器(即使在 IE 上)运行得更好,并且也可以完美地与所有浏览器一起工作。

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

  1. $.ready()使开发人员可以轻松地以正确的顺序做事。特别是,关键是不要引用尚未加载的 DOM 元素。虽然这很简单,但许多开发人员仍然感到困惑。$.ready()很简单,尽管速度很慢。
  2. 在您说过几个需要的脚本时,在您的身体末尾手动init()执行此操作并不一定容易/方便。它需要纪律和了解这些脚本的作用。特别是您会经常在依赖 jQuery 的库中看到,因为无论开发人员使用何种方式加载库,它都能让事情正常工作。$.ready()
  3. 随着异步模块定义(例如require.js)作为一种加载 javascript 的方式变得流行,<body/>方法的结束并不能保证。
于 2012-03-04T20:40:16.013 回答
6

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

由于您希望模板可以在使用它们的任何页面上工作,因此您需要在其中包含必要的 Javascript。对于这些情况,该ready()功能是真正的救生员。

于 2012-03-04T19:01:36.170 回答
2

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

当涉及到您可以完全控制的页面时,显然您不必担心,因此我认为使用 document.ready 而不是init()从正文末尾调用您的页面更“安全” . 使用 document.ready(或 onload)并将脚本放在正文末尾是两种最常见的方法,它们很常见,因为它们都运行良好。

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

于 2012-03-04T20:38:22.143 回答
0

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

很容易优化指标,而不是实际的用户体验。所以“真正的用户优化”图下降了,即使交互性被延迟了。

于 2013-11-13T00:26:46.680 回答