2009-04-13 53 views
5

因爲我使用jQuery 1.3+除了一個定時測試正在使用它。另一個是我在2000年發現的純javascript。我停止了這條路線,因爲它需要大約150秒來運行測試。我已經閱讀了很多與選擇單個元素相關的jQuery優化網頁。 '#id'是使用它的最好情況,但現在我有檢查一個列中的所有複選框在一個相當大的表中有多個複選框列的問題。什麼是選擇大量複選框並取消/選擇它們的最快方法?

我所做的是設置一個頁面,創建兩個複選框列的20,000錶行。目標是檢查第二欄,看看花了多長時間,然後取消選中它們,看看花了多長時間。顯然我們想要最短的時間。我只使用IE6和7,在我的情況下,我的所有用戶都會這樣做。

你說20000行?這也是我所說的,但這是生產(我手中沒有),現在改變已經太遲了。我只是想在時鐘上留下1秒鐘的雹子。另外,我知道input.chkbox不是最快的選擇器(對於IE7)! :)

問題是,有沒有更好的方法來做這個jQuery或以其他方式嗎?我希望它能在我的機器上運行不到半秒鐘。

所以你不必重新輸入所有我已經在這裏做的廢話是測試的東西,我想出了:

更新上午4/14,包括進一步的試運行時間:

<form id="form1" runat="server"> 
<div>   
     <a href="#" id="one">input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="two">#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="three">#myTable tr.myRow input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="four">tr.myRow input[id^='chkbox'][type='checkbox']</a><br /> 
     <a href="#" id="five">input[id^='chkbox']</a><br /> 
     <a href="#" id="six">.chkbox</a><br /> 
     <a href="#" id="seven">input.chkbox</a><br /> 
     <a href="#" id="eight">#myTable input.chkbox</a><br /> 

     <a href="#" id="nine">"input.chkbox", "tr"</a><br /> 
     <a href="#" id="nine1">"input.chkbox", "tr.myRow"</a><br /> 
     <a href="#" id="nine2">"input.chkbox", "#form1"</a><br /> 
     <a href="#" id="nine3">"input.chkbox", "#myTable"</a><br /> 

     <a href="#" id="ten">input[name=chkbox]</a><br /> 
     <a href="#" id="ten1">"input[name=chkbox]", "tr.myRow"</a><br /> 
     <a href="#" id="ten2">"input[name=chkbox]", "#form1"</a><br /> 
     <a href="#" id="ten3">"input[name=chkbox]", "#myTable"</a><br /> 

     <a href="#" id="ten4">"input[name=chkbox]", $("#form1")</a><br /> 
     <a href="#" id="ten5">"input[name=chkbox]", $("#myTable")</a><br /> 

     <a href="#" id="eleven">input[name='chkbox']:checkbox</a><br /> 
     <a href="#" id="twelve">:checkbox</a><br /> 
     <a href="#" id="twelve1">input:checkbox</a><br /> 
     <a href="#" id="thirteen">input[type=checkbox]</a><br /> 

     <div> 
      <input type="text" id="goBox" /> <button id="go">Go!</button> 
      <div id="goBoxTook"></div> 
     </div> 

     <table id="myTable"> 
      <tr id="headerRow"><th>Row #</th><th>Checkboxes o' fun!</th><th>Don't check these!</th></tr> 
      <% for(int i = 0; i < 20000;i++) { %> 
      <tr id="row<%= i %>" class="myRow"> 
       <td><%= i %> Row</td> 
       <td> 
        <input type="checkbox" id="chkbox<%= i %>" name="chkbox" class="chkbox" /> 
       </td> 
       <td> 
        <input type="checkbox" id="otherBox<%= i %>" name="otherBox" class="otherBox" /> 
       </td> 
      </tr> 
      <% } %> 
     </table> 
</div> 
     <script type="text/javascript" src="<%= ResolveUrl("~/") %>Javascript/jquery.1.3.1.min.js"></script> 
     <script type="text/javascript"> 

      $(function() {     
       function run(selectorText, el) {      
        var start = new Date();      
        $(selectorText).attr("checked", true);        
        var end = new Date(); 
        var timeElapsed = end-start; 
        $(el).after("<br />Checking Took " + timeElapsed + "ms"); 

        start = new Date();      
        $(selectorText).attr("checked", false);        
        end = new Date(); 
        timeElapsed = end-start; 
        $(el).after("<br />Unchecking Took " + timeElapsed + "ms"); 
       }  

       function runWithContext(selectorText, context, el) {      
        var start = new Date();      
        $(selectorText, context).attr("checked", true);        
        var end = new Date(); 
        var timeElapsed = end-start; 
        $(el).after("<br />Checking Took " + timeElapsed + "ms"); 

        start = new Date();      
        $(selectorText, context).attr("checked", false);         
        end = new Date(); 
        timeElapsed = end-start; 
        $(el).after("<br />Unchecking Took " + timeElapsed + "ms"); 
       } 

       $("#one").click(function() {       
        run("input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#two").click(function() { 
        run("#myTable tr[id^='row'] input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#three").click(function() { 
        run("#myTable tr.myRow input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#four").click(function() { 
        run("tr.myRow input[id^='chkbox'][type='checkbox']", this); 
       }); 

       $("#five").click(function() { 
        run("input[id^='chkbox']", this); 
       }); 

       $("#six").click(function() { 
        run(".chkbox", this); 
       }); 

       $("#seven").click(function() { 
        run("input.chkbox", this); 
       }); 

       $("#eight").click(function() { 
        run("#myTable input.chkbox", this); 
       }); 

       $("#nine").click(function() { 
        runWithContext("input.chkbox", "tr", this); 
       }); 


       $("#nine1").click(function() { 
        runWithContext("input.chkbox", "tr.myRow", this); 
       }); 
       $("#nine2").click(function() { 
        runWithContext("input.chkbox", "#form1", this); 
       }); 
       $("#nine3").click(function() { 
        runWithContext("input.chkbox", "#myTable", this); 
       }); 

       $("#ten").click(function() { 
        run("input[name=chkbox]", this); 
       });     

       $("#ten1").click(function() { 
        runWithContext("input[name=chkbox]", "tr.myRow", this); 
       }); 

       $("#ten2").click(function() { 
        runWithContext("input[name=chkbox]", "#form1", this); 
       }); 

       $("#ten3").click(function() { 
        runWithContext("input[name=chkbox]", "#myTable", this); 
       }); 

       $("#ten4").click(function() { 
        runWithContext("input[name=chkbox]", $("#form1"), this); 
       }); 

       $("#ten5").click(function() { 
        runWithContext("input[name=chkbox]", $("#myTable"), this); 
       }); 

       $("#eleven").click(function() { 
        run("input[name='chkbox']:checkbox", this); 
       }); 

       $("#twelve").click(function() { 
        run(":checkbox", this); 
       }); 

       $("#twelve1").click(function() { 
        run("input:checkbox", this); 
       }); 

       $("#thirteen").click(function() { 
        run("input[type=checkbox]", this); 
       }); 

       $('#go').click(function() { 
        run($('#goBox').val(), this); 
       }); 
      }); 
     </script> 
</form> 
+0

我並不意味着無益,但在一頁中的20k行只是壞的設計。你應該解決這個問題。 :) – 2009-04-13 23:24:19

+0

呃...沒有開玩笑。 :)我沒有做到!現在沒有足夠的時間爲此版本修復它。這將是下一個版本首先要做的事情。儘管如此,這個項目帶來了許多「有趣」的挑戰。 – rball 2009-04-13 23:31:07

回答

8

輸入[名稱= chkbox]是IE7下我機器上最快的jQuery選擇器。

Unchecking Took 2453ms 
Checking Took 2438ms 
Unchecking Took 2438ms 
Checking Took 2437ms 
Unchecking Took 2453ms 
Checking Took 2438ms 

input.chkbox和...

Unchecking Took 2813ms 
Checking Took 2797ms 
Unchecking Took 2797ms 
Checking Took 2797ms 
Unchecking Took 2813ms 
Checking Took 2797ms 

輸入:checkbox.chkbox似乎很依賴

Unchecking Took 2797ms 
Checking Took 2797ms 
Unchecking Took 2813ms 
Checking Took 2781ms 

.chkbox的兩倍,幾乎需要爲input.chkbox

Unchecking Took 4031ms 
Checking Took 4062ms 
Unchecking Took 4031ms 
Checking Took 4062ms 

for循環中的JavaScript是迄今爲止最糟糕的進來:

Checking Took 149797ms 

150秒!它也鎖定瀏覽器。這讓我對jQuery印象深刻。我真的沒想到它會那麼慢。可能是因爲我正在通過每個單獨的元素,然後它必須找到...

這相當有趣,我還有:

輸入[ID^= 'chkbox']

Unchecking Took 3031ms 
Checking Took 3016ms 

的時間比:

輸入[ID^='chkbox'] [type ='checkbox']

Unchecking Took 3375ms 
Checking Took 3344ms 

我以爲我發佈了更多的過濾器會更快。不!

指定更路徑的複選框使得方式較慢:

#myTable TR [ID^= '行']輸入[ID^= 'chkbox'] [式= '複選框']

Checking Took 10422ms 

它甚至沒有運行第二個取消選中,因爲它問我是否想繼續在我的電腦上運行腳本。瘋! :P

更新上午4/14:

有人提出了設置背景:其實我做了幾那些使我很吃驚的和反對的正是很多人都在網絡上說在IE7上,這些速度較慢!下面是我用幾個不同的上下文中的指定用更快的選擇器的上方配對拿到了時間:

「input.chkbox」, 「TR」

Checking Took 8546ms 

「input.chkbox」,「TR .myRow」

Checking Took 8875ms 

「input.chkbox」, 「#form1的」

Unchecking Took 3032ms 
Checking Took 3000ms 

「input.chkbox」, 「#myTable」

Unchecking Took 2906ms 
Checking Took 2875ms 

當前勝者(靜止):輸入[名稱= chkbox]

Unchecking Took 2469ms 
Checking Took 2453ms 

「輸入[名= chkbox]「,」tr。myRow」

Checking Took 9547ms 

「輸入[名稱= chkbox]」, 「#form1的」

Unchecking Took 3140ms 
Checking Took 3141ms 

「輸入[名稱= chkbox]」, 「#myTable」

Unchecking Took 2985ms 
Checking Took 2969ms 

更新2上午4/14

以爲我注意到與http://beardscratchers.com/journal/jquery-its-all-about-context的語法差異後,可能會有更好的一個。看起來這些與不一樣,他們給出的時間稍微好一些,但仍然沒有擊敗非競爭選擇器 - darn。

「輸入[名稱= chkbox]」,$( 「#form1中」)

Unchecking Took 3078ms 
Checking Took 3000ms 
Unchecking Took 3078ms 
Checking Took 3016ms 

「輸入[名稱= chkbox]」,$( 「#myTable的」)

Unchecking Took 2938ms 
Checking Took 2906ms 
Unchecking Took 2938ms 
Checking Took 2921ms 

更新3晨4/14

拉斯想讓我嘗試這些了,他們去/選擇所有的微博XES但同樣很有意思:

:複選框

Unchecking Took 8328ms 
Checking Took 6250ms 

輸入:複選框

Unchecking Took 5016ms 
Checking Took 5000ms 

- >最快?!?! 輸入[類型=複選框]

Unchecking Took 4969ms 
Checking Took 4938ms 

第三那裏是最快的,這一事實就是這麼違背了我本來以爲挺有意思的。爲什麼不(對於IE7來說):複選框只是使用type =複選框來獲得更快的時間?這些分數非常接近,但檢查時間縮短了62ms。另外,爲什麼前兩個不同呢?除了可以帶有複選框的輸入外,是否還有其他元素?

5

我還沒有測試過這個,但是你可以嘗試在頁面加載時創建一個數組[]的複選框引用,然後簡單地迭代每次你想做出改變?

您會在頁面加載時支付性能成本,但其可能是比每次步行DOM都快。嘿,至少你會在用戶'停機時間'中執行繁重的工作(人們需要多長時間才能找到並單擊取消選擇/選擇選項)。

+0

或者我想知道是否可以在第一次(或在加載時)將它們「緩存」到數組中,然後當它們再次打開時它會更快。很酷的想法,我會放手一搏。 – rball 2009-04-13 23:18:44

+0

讓我知道你如何得到! – Codebrain 2009-04-13 23:19:36

+0

會做,但可能是明天,因爲工作日快要結束了。 – rball 2009-04-13 23:20:58

2

我唯一的建議可能不會工作。切換瀏覽器。但我只有一家公司實際上同意這一點。我們將公司切換到FireFox,並且特定用戶轉移到Google Chrome。 IE瀏覽器對JavaScript來說太慢了。

此外,您可以嘗試預先緩存jQuery查詢列表。

如果一切都失敗了,用心理學解決。這意味着讓用戶知道某些事情需要很長時間。在功能執行時放置一個「Please wait」div。這樣用戶就知道瀏覽器不僅僅是鎖定了,而且他們知道什麼時候可以重新開始工作。通過這樣做,我已經解決了很多慢頁面。

1

您是否嘗試過使用context來查看jQuery選擇器是否可以提高性能?據推測,這些控件將位於ASP.NET表單中,並且可能是另一個獨特的可識別元素?

例如,如果你有

$("input[id^='chkbox']") 

上下文與

$("input[id^='chkbox']", "#myFormID") 

Here's a BeardScratchers article嘗試

編輯:

按照你的更新,它似乎像2.45- 6秒根據你的情況,這可能是你能達到的最快速度。

只是爲了完整性,您是否嘗試過以下選擇器?

$(':checkbox') 
$('input[type=checkbox]') 
相關問題