2013-04-09 33 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