为什么jQuery.ready这么慢却被推荐
Why is jQuery.ready recommended when it’s so slow?
我以前也问过类似的问题,但我从来没有明确表达过我的观点,或者至少我认为这是一个非常相关的问题,值得提出来,看看是否有人能给出一些有见地的想法。
在使用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()
,在您的情况下,它们可能不适用:
$.ready()
使开发人员可以很容易地按照正确的顺序进行操作。特别是,关键是不要引用尚未加载的DOM元素。虽然这很简单,但许多开发人员仍然感到困惑。$.ready()
是一个无需思考的问题,尽管速度很慢- 在您已经说过的几个需要
init()
的脚本中,在您的身体末端手动这样做并不一定容易/方便。它需要对这些脚本的作用进行规范和了解。特别是,在依赖jQuery的库中,您经常会看到$.ready()
,因为无论开发人员使用何种方式加载库,它都能使事情正常工作 - 随着异步模块定义(例如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变慢。
很容易根据指标进行优化,而不是根据实际用户体验进行优化。因此,"真正的用户优化"图会下降,即使交互性会延迟。
- 单击轨道link_to后,jQuery ready 未触发
- 从 jquery.ready() 调用的 javascript 何时相对于 中的脚本运行
- jQuery .ready is not working
- 在 JavaScript 中延迟加载,Jquery 'ready()' 在加载 JQuery 之前运行
- jquery ready handler 从未执行过
- jquery .ready and height of element
- jquery ready 函数在我单击锚标记时执行两次
- jQuery .ready method
- Binding jQuery ready and ajaxStop
- jQuery .ready() 调用一个 javascript 对象,不起作用
- jQuery .ready() 和