2013-04-09 43 views
3

我正在写一些jQuery代码,它可以同时隐藏或显示大表中的大量表列。我想知道这将是更快地使用这样的代码:性能与可读性:多选择器与jQuery/JS中的多个语句

$("selector 1, selector 2, selector 3").css("display", "none"); 

或代码:

$("selector 1").css("display", "none"); 
$("selector 2").css("display", "none"); 
$("selector 3").css("display", "none"); 

所以我用jsperf.com to create a performance test case。因此,我确定第一种类型的代码(使用一个具有多个选择器的长字符串)比第二种类型的代码(一次隐藏一列)要快53%左右。然而,我写完它的时候,它会被边缘不可读,看起来像这样:

$("#table tr *:nth-child(4), #table tr *:nth-child(5), #table tr *:nth-child(6), #table tr *:nth-child(7), #table tr *:nth-child(8), #table tr *:nth-child(9), #table tr *:nth-child(10), #table tr *:nth-child(11), #table tr *:nth-child(12)").css("display", "none"); 

所以我的问题是,这是jQuery的/ JS代码大恶 - 效率低下的表现,或缺乏可读性?我的背景是Python,所以我倾向于将可读性看作高于性能,53%似乎并不像现实世界中的巨大下降。但另一方面,我打算一旦部署了我的JS代码就会缩小它的大小,所以它最终不会被读取......尽管我知道有那些可以将我的代码返回到其原始可读或不可读的形式。正如你所看到的,我可以在这个主题上围绕自己讨论,而且我不打算开始辩论或讨论,所以我只是在这里发布,以防在jQuery/JS社区。

回答

3

也许你只需要考虑替代方法来编写代码,并有两个世界。例如:

var nth = [4,5,6,7,8,9,10,11,12]; 

$('#table tr *') 
    .filter(':nth-child('+ nth.join('),:nth-child(') +')') 
    .css('display', 'none'); 
+0

有趣的是,在基准测试中,我发现这个方法实际上比多语句方法慢。 – GChorn 2013-04-09 06:27:28

+0

我想你可能会测试错误...使用“setup”字段来定义你的初始变量,否则你也会在测试中引入数组的创建。我尝试了一堆浏览器,这比多个选择器快。 http://jsperf.com/6b11404dd2f0 – elclanrs 2013-04-09 06:35:47

+0

奇怪的是,当我测试@ Ian的版本时没有针对单语句与长选择器版本进行变量设置时,他们的表现差不多。当我和你一起做的时候,速度要慢得多。但是当我直接测试你的版本与Ian的版本时,它稍微快了一点。这一切都没有预先定义的变量。但是你是对的,在我的实际代码中,我只能定义一次变量,如果我这样做,那么你的代码的两个代码比多个语句的代码要快得多。不管怎样,谢谢! – GChorn 2013-04-09 08:35:12

2

它可能应该取决于该代码如何被经常打(它是一个页面的生命周期内运行一次?它是连接到一个定时器或点击事件或东西,可能会导致它开火多次?)

我总是倾向于可读性而非效率直到/除非您确定某些代码是瓶颈并需要优化。请记住关于过早优化的经典编程课程。

另外请记住,您的jsperf测试可能会在浏览器和客户端(尤其是旧的IE和手机)之间大幅变化。由于ECMA实施方式的差异,有时甚至会在最新版本的Firefox和Chrome之间看到巨大的性能差异!

最后,53%的差异听起来像是用百分比表示的很多,但以毫秒为单位查看时间并自行确定这是否会成为应用程序的潜在瓶颈。

2

确定值的可读性高于性能。毕竟你使用的是JS。也就是说你可以用可读的方式提高性能。例如使用更易于理解的循环生成此选择器,而不是内联的巨大字符串。

此外,缩小你不应该覆盖你的代码。对于任何修改,您仍然可以回到非缩小版本,进行编辑并再次缩小。缩小的代码适用于浏览器而非人眼。因此,关于其可读性的任何评论都是无关紧要的。

2

您可以存储选择在一个数组,然后在需要的时候他们加入他们的行列:

var selectors = [ 
    "selector 1", 
    "selector 2", 
    "selector 3" 
]; 
$(selectors.join(", ")).css("display", "none"); 

你的长期选择工作的原因是因为只有一个jQuery对象被创建,并且只可以调用一个浏览器方法,提高速度。我猜document.querySelectorAll会被使用,并可以传递整个选择器并返回结果。虽然jQuery会调用n号码document.querySelectorAll方法n号码$().css调用。

另一种选择,是使用.add方法来“改善”可读性:

var selectors = $("selector 1"); 
selectors.add("selector 2"); 
selectors.add("selector 3"); 
selectors.css("display", "none"); 

虽然我敢肯定,这将是比多选择/ css语句快,也不会那么快作为document.querySelectorAll的能力与一个大选择器。

+0

你的第一种方法看起来和@ elclanrs很相似,但是性能明显提高。事实上,它比我长时间选择的单个语句表现得更好。我想知道为什么? – GChorn 2013-04-09 06:33:05

+0

@GChorn哈哈,没有任何意义(为什么它比你的原始速度快)。我的**基本上**生产**你的原创。但是在数组中存储并且不得不调用'join'时,我只会认为它可能会变慢。 elclanrs的解决方案稍微复杂一些;我只是试图以不同的方式存储/检索选择器。 – Ian 2013-04-09 06:35:51

+0

糟糕,是的,我刚刚注意到,当我基准测试两种方法时,我给列表变量比原始语句少了两个选择器。现在他们正在测试相同的东西。 – GChorn 2013-04-09 08:04:40