jQuery优化/最佳实践

时间:2010-07-12 17:38:47

标签: javascript jquery sizzle

好的马鞍牛仔,因为这将是一个漫长的。我早上花了一些旧的代码,我不知道最佳实践和优化。为了避免乘坐主观道路,我会发布一些例子,希望能够轻松回答问题。我将尽量使示例非常简单,以便于回答并减少出错的可能性。我们走了:

1)分配与jQuery调用

我理解当访问选择器时,通常认为将选择器分配给变量而不是多次进行相同的调用会更好 - 例如

$('div#apples').hide();
$('div#apples').show();

VS

var oranges = $('div#oranges');
oranges.show();
oranges.hide();

引用jQuery的$(this)时是否适用同样的规则?防爆。一个简单的脚本,可以使表中的某些数据可单击并自定义链接。

$('tr td').each( function() {
    var colNum = $(this).index();
    var rowNum = $(this).parent().index();
    $(this).wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">'); 
})

VS

$('tr td').each( function() {
    var self = $(this);
    var colNum = self.index()
    var rowNum = self.parent().index()
    self.wrap('<a href="example.com/hello.html?column=' + colNum + '&row=' + rowNum +'">'); 
});

2)this vs $(this)

好的,所以下一个是我长期以来一直想知道的东西,但我似乎找不到任何关于它的信息。请原谅我的无知。什么时候调用vanilla js this而不是jQuery包裹$(this)是什么意思?这是我的understanding -

$('button').click(function() {
  alert('Button clicked: ' + $(this).attr('id'));
});

效率远低于访问vanilla this对象的DOM属性,如下所示 -

$('button').click(function() {
  alert('Button clicked: ' + this.id);
});

我理解那里发生了什么,我只是想知道在决定使用哪一条时是否有一条经验法则。

3)更具特异性总是更好吗?

这个很简单,对我们的选择器更具体是否总是有益的?很容易看出$('.rowStripeClass')$('#tableDiv.rowStripeClass')慢得多,但我们在哪里划线? $('body div#tableDiv table tbody tr.rowStripeClass')还能更快吗?任何意见都将不胜感激!

如果你已经做到这一点,谢谢你看看!如果你还没有,:p

6 个答案:

答案 0 :(得分:37)

我会尽量简明扼要地回答这些问题:

  1. 在循环使用时经常使用缓存,特别是,运行相同的代码来获取相同的结果从来没有一个好的表现,缓存它。

  2. 当您只需要一个DOM元素时使用this,当您需要the jQuery methods时使用$(this)(否则将无法使用),{{1} } vs this.id是完美的,一些更常见的例子:

    • 使用$(this).attr("id")代替this.checked
    • 使用$(this).is(':checked')代替$.data(this, 'thing')
    • 创建jQuery对象的任何其他情况基本上都没用。
  3. 从ID选择器下降是性能的首选...您需要具体的具体程度如何?简而言之,这完全取决于:具体到您需要

答案 1 :(得分:9)

1)分配与jQuery调用

  

引用jQuery的$(this)时是否适用同样的规则?

是的,绝对的。对$函数的调用会创建一个新的jQuery对象,并带来相关的开销。使用相同的选择器多次调用$将每次创建一个新对象。

2)这vs $(this)

我想说知道差异很重要,因为有时你不用jQuery包装你的对象变得至关重要。在大多数情况下,您不希望进行过早优化,只是为了保持一致,总是用$(this)包装它们,最好将它缓存在变量中。但是,请考虑包含一百万个<ul>元素的无序列表<li>的极端示例:

$("#someList  li").each(function() {
    var id = $(this).attr('id');
});

创建了一百万个新对象,这些对象会在不创建任何新对象的情况下完成性能损失。对于在所有浏览器中保持一致的属性和属性,您可以直接访问它们而无需将其包装在jQuery中。但是,如果这样做,请尝试将其限制为处理大量元素的情况。

3)更具特异性总是更好吗?

并非总是如此。它主要依赖于浏览器,并且再次不值得深入研究微优化,除非您确定某些内容在您的应用程序中运行得相当慢。例如:

$("#someElement") vs $("#someElement", "#elementsContainer")

可能看起来因为我们在按id搜索元素时也提供了一个上下文,所以第二个查询会更快,但是相反。第一个查询转换为对本机getElementById(..)的直接调用,而第二个查询则由于上下文选择器而不转换。

此外,某些浏览器可能会提供一个接口来使用getElementsByClassName按类名访问元素,并且jQuery可能会将它用于这些浏览器以获得更快的结果,在这种情况下,提供更具体的选择器,例如:

$("#someElement.theClass")

可能实际上是一个障碍,而不仅仅是写作:

$(".theClass")

答案 2 :(得分:4)

此博客不是太过时,但它提供了一些问题的答案,并提供了有关使用jquery时加快网站速度的更多信息:http://www.artzstudio.com/2009/04/jquery-performance-rules/

我最喜欢的一个是第六号,它声明限制DOM操作。因为每次附加到DOM时,在for循环中执行.append总是一件坏事,这是一项昂贵的操作。

答案 3 :(得分:4)

直到你的问题:

  1. 缓存jQuery对象应该会产生最佳性能。它将避免DOM查找,这是多次执行时可能会变慢的。您可以从jQuery链中受益 - 有时不需要局部变量。
  2. this是DOM元素时,$(this)也是如此。尽管这是获取jQuery对象的最快方法,但它仍然比缓存慢。如果vanilla DOM元素就足够了 - 那么根本不要调用jQuery。 id属性的例子非常好 - 比$(this).attr('id)更喜欢this.id,如果你不需要$(this)
  3. 更具体的选择器确实会减少DOM查找时间。然而,确实有一条线要做 - 只有当你100%确定这会以明显的方式改善性能时,才能使选择器更具体。

答案 4 :(得分:3)

您应该关注的情况是循环事件。因为您在其中一个中所做的每个动作都将在每次迭代或每个事件中完成。

  1. 分配与jQuery通话

    你的榜样不是最好的。您应该保存对jQuery对象的引用的位置是循环事件中使用的位置,或者是复杂查询的结果。

  2. 此vs $(此)

    再次在性能关键情况下原始dom 更好。 其他比你应该选择的更短或更多可读。令人惊讶的是,它并不总是jQuery。

  3. 更具特异性总是更好吗?

    更多类型的特异性通常会被人们混淆。 其中一个无用的,例如:id选择器tag#id的标记名称,它将比简单ID慢。但是,当巨大利益具体时,另一种类型。 现在这种类型取决于浏览器,因为现代版本将牺牲旧版本,但值得权衡这种情况发生在为tag class指定tag.class时。在IE 6-7中,它将比简单的.class快得多,因为sizzle可以使用快速document.getElementsByTagName函数。现在另一个类型是指定过多的祖先。这会在每个浏览器中减慢速度。这是因为选择器从右到左执行。要记住的规则:始终是最右边的选择器尽可能具体

答案 5 :(得分:1)

2013年关于最佳jQuery实践的博客文章

更新了您的问题的答案,甚至更多关于现在应用的最佳jQuery实践,this article正在处理非常有用并且您可能想要阅读的有趣主题。

它涉及这里提到的主题甚至更多:动画函数,jQuery承诺,导入jQuery的最佳方法,jQuery事件等。 希望对您有所帮助!