2009-04-13 9 views
5

Da ich jQuery 1.3+ benutze alle außer einem zeitgesteuerten Test verwendet. Das andere ist einfaches Javascript, das ich im Jahr 2000 gefunden habe. Ich habe aufgehört, diesen Weg zu gehen, da es ungefähr 150 Sekunden dauerte, um den Test durchzuführen. Ich habe eine ganze Reihe von jQuery-Optimierungswebseiten gelesen, die sich auf die Auswahl eines einzelnen Elements beziehen. Ein "#id" ist der beste Fall für die Verwendung, aber jetzt habe ich das Problem von alle Kontrollkästchen in einer Spalte in einer ziemlich großen Tabelle, die mehrere Checkbox-Spalten hat.Was ist der schnellste Weg, um eine große Anzahl von Checkboxen auszuwählen und zu deaktivieren?

Ich habe eine Seite eingerichtet, die 20.000 Tabellenzeilen mit zwei Kontrollkästchen-Spalten erstellt. Das Ziel ist es, die zweite Spalte zu überprüfen, wie lange das gedauert hat, und dann die Häkchen zu entfernen und zu sehen, wie lange das gedauert hat. Offensichtlich wollen wir die niedrigste Zeit. Ich benutze nur IE6 und 7 und in meinem Fall werden alle meine Benutzer das gleiche tun.

20.000 Zeilen, die Sie sagen? Das habe ich auch gesagt, aber das wird zur Produktion (aus meiner Hand) und es ist zu spät, um es jetzt zu ändern. Ich versuche nur einen Hail Mary mit 1 Sekunde auf der Uhr zu werfen. Außerdem habe ich gelernt, dass input.chkbox nicht der schnellste Selektor (für IE7) ist! :)

Die Frage ist, gibt es eine bessere Möglichkeit, diese jQuery oder sonst? Ich würde es lieben, in weniger als einer halben Sekunde auf meiner Maschine zu laufen.

So haben Sie nicht den ganzen Mist in das Feld eintragen ich bereits hier getan habe ist der Test Sachen, die ich kam mit:

Aktualisiert Morgen 4/14 weitere Zeit Studien umfassen:

<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

Ich meine nicht, nicht hilfreich, aber 20k Zeilen auf einer Seite ist nur schlechtes Design. Sie sollten das reparieren. :) –

+0

Nun ... kein Scherz. :) Ich habe es nicht getan! Momentan ist nicht genug Zeit, um es für diese Version zu reparieren. Dies wird bei der nächsten Veröffentlichung das erste Mal sein. Dieses Projekt hat bisher viele "interessante" Herausforderungen aufgeworfen. – rball

Antwort

8

eingang [name = chkbox] kommt als der schnellste jQuery Selektor auf meinem Rechner unter IE7.

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

input.chkbox und ...

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

Eingang: checkbox.chkbox scheinen gebunden

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

.chkbox fast doppelt so lang wie die Takes input.chkbox

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

Die Javascript for-Schleife ist bei weitem das Schlimmste in bei kommenden:

Checking Took 149797ms 

150 Sekunden! Es sperrt den Browser auch. Das macht mich wirklich beeindruckt von jQuery. Ich habe ehrlich gesagt nicht erwartet, dass es so langsam ist. Wahrscheinlich, weil ich jedes einzelne Element passiere, das es dann finden muss ...

Eingang [id^= 'chkbox']

Unchecking Took 3031ms 
Checking Took 3016ms 

nahm weniger Zeit als:

Dieses ziemlich interessant für mich auch war

Eingang [id^= 'chkbox'] [type = 'checkbox']

Unchecking Took 3375ms 
Checking Took 3344ms 

Ich dachte, seit ich mehr Filter gepostet habe, wäre es schneller. Nee!

noch mehr Pfade zum Angeben Checkbox macht es langsamer Weise:

#myTable tr [id^= 'Reihe'] -Eingang [id^= 'chkbox'] [type = 'Ankreuzfeld']

Es hat nicht einmal die zweite Deaktivierung ausgeführt, da es mich fragte, ob ich weiterhin Skripts auf meinem Computer ausführen wollte. Verrückt! : P

aktualisieren Morgen 4/14:

Jemand brachte den Kontext Einstellung: Ich habe tatsächlich ein paar von denen, und viel zu meiner Überraschung und gegen das, was viele Leute auf dem Netz gesagt haben auf IE7 waren diese langsamer! Hier sind die Zeiten, die ich mit einigen anderen Kontext des angegebenen gepaart bekam mit dem schnelleren Selektor des oben:

"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 

aktuelle Gewinner (noch): Eingang [name = chkbox]

Unchecking Took 2469ms 
Checking Took 2453ms 

„input [name = chkbox] "," tr.myRow“

Checking Took 9547ms 

"input [name = chkbox]", "# form1"

Unchecking Took 3140ms 
Checking Took 3141ms 

"input [name = chkbox]", "#myTable"

Unchecking Took 2985ms 
Checking Took 2969ms 

Update 2 Morgen 4/14

Ich dachte, ich könnte eine bessere gehabt haben, nachdem ich einen Syntaxunterschied von http://beardscratchers.com/journal/jquery-its-all-about-context bemerkte. Es scheint, dass diese sind nicht das gleiche wie geben sie etwas bessere Zeiten, aber immer noch nicht die nicht kontextuelle Selektor - verdammt schlagen.

"input [name = chkbox]", $ ("# form1")

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

"input [name = chkbox]", $ ("# myTable")

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

Update 3 Morgen 14.04

Russ wollte, dass ich diese aus, um zu versuchen, sie de/wählen sie das ALL bo xes, aber es war wieder interessant:

: Checkbox

Unchecking Took 8328ms 
Checking Took 6250ms 

Eingang: Checkbox

Unchecking Took 5016ms 
Checking Took 5000ms 

-> Schnellste?!?! input [type = Checkbox]

Unchecking Took 4969ms 
Checking Took 4938ms 

Die Tatsache, dass der dritte dort die schnellste ist recht interessant, wie das geht gegen das, was hätte ich gedacht. Warum sollte (zumindest für IE7) das: -Kontrollkästchen einfach das Type = -Kästchen benutzen, um eine schnellere Zeit zu erreichen? Das sind wirklich enge Ergebnisse, aber die Überprüfung dauerte 62ms weniger Zeit. Warum unterscheiden sich die ersten beiden überhaupt? Gibt es neben einer Eingabe ein anderes Element, das ein Kontrollkästchen haben kann?

+0

Weitere Auswahlkriterien beschleunigen die Abfrage nicht, es sei denn, sie reduzieren die Satzgröße. Da alle Kontrollkästchen in Tabellenzeilen stehen und Eingaben enthalten, hilft das Hinzufügen dieser Kriterien nicht. –

+0

"Ich dachte, seit ich mehr Filter gepostet habe, wäre es schneller." wie Zan sagte, mehr Filter = mehr Checks = mehr Verarbeitung = mehr Zeit. Wenn nicht jeder Filter die eingestellte Größe für den nächsten Filter signifikant reduziert, nimmt er nur Zyklen in Anspruch. – nickf

5

Ich habe das nicht getestet, aber Sie könnten versuchen, ein Array [] von Checkbox-Referenzen beim Laden der Seite zu erstellen, dann iterieren Sie einfach jedes Mal, wenn Sie eine Änderung vornehmen möchten?

Sie würden die Kosten für die Leistung beim Laden der Seite zahlen, aber könnte schneller sein als jedes Mal das DOM zu gehen. Hey, zumindest würdest du das schwere Heben in der Downtime des Benutzers durchführen (wie lange dauert es, bis die Leute die Auswahl-/Auswahloptionen finden und anklicken).

+0

Oder ich frage mich, ob Sie sie beim ersten Mal (oder beim Laden) in ein Array "zwischenspeichern" könnten, und dann wäre es schneller, wenn sie es wieder treffen. Coole Idee, ich werde es versuchen. – rball

+0

lass mich wissen, wie es dir geht! – Codebrain

+0

Wird, aber könnte morgen sein, da der Arbeitstag fast zu Ende gegangen ist. – rball

2

Mein einziger Vorschlag wird wahrscheinlich auch nicht funktionieren. Browser wechseln Aber ich habe nur einer Firma zugestimmt. Wir haben die Firma zu FireFox wechseln lassen, und bestimmte Nutzer wechseln zu Google Chrome. IE ist einfach zu langsam mit JavaScript.

Sie können auch versuchen, die jquery-Abfrageliste vorab zwischenzuspeichern.

Wenn alles andere fehlschlägt, lösen Sie es mit Psychologie. Das bedeutet, dass der Benutzer wissen muss, dass etwas lange dauern wird. Stellen Sie während der Ausführung der Funktion einen "Bitte warten" -Videor auf. Auf diese Weise weiß der Benutzer, dass der Browser nicht nur gesperrt ist, und er weiß, wann er wieder arbeiten kann. Ich habe viele langsame Seiten "gelöst", indem ich genau das getan habe.

+0

Lol, ja, das wird einfach nicht passieren. Ich bin "glücklich" genug, IE7 benutzen zu können. Alle anderen müssen IE6 verwenden. Ich werde in Pre-Caching schauen. – rball

+0

Eine andere Option ... Sie verwenden die JQuery-Attributmanipulation für die Einstellung checked: $ (selectorText) .attr ("checked", false); Sie könnten auch versuchen $ (selectorText) .each (function() {this.checked = false}); Keine Garantien, aber es könnte einen Versuch wert sein. –

+0

Dachte daran, das zu tun. Ich werde es versuchen und sehen, was passiert. Wir geben tatsächlich eine Benachrichtigung von Bitte warten, bevor es 150 Sekunden war, aber es auf 2-3 zu bringen wird großartig. – rball

1

Haben Sie die jQuery-Selektoren mit einer ausprobiert, um zu sehen, ob das die Leistung verbessert? Vermutlich befinden sich die Steuerelemente in einem ASP.NET-Formular und möglicherweise einem anderen eindeutig identifizierbaren Element?

Zum Beispiel, wo Sie

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

mit

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

Here's a BeardScratchers article auf Kontext

EDIT:

Nach Ihrem Updates, wie es scheint, 2.45- 6 Sekunden könnte der schnellste sein, den Sie aufgrund Ihrer Umstände erreichen können.

Nur der Vollständigkeit halber, haben Sie die folgenden Selektoren ausprobiert?

$(':checkbox') 
$('input[type=checkbox]') 
+0

Scheint langsamer zu sein. Vielleicht habe ich den "richtigen" Kontext aber noch nicht bekommen ... – rball

+0

Aktualisierter Beitrag mit Ergebnissen. – rball

+0

Warten Sie ... ganzen Artikel lesen, sieht aus wie ich habe den Kontext falsch zur Verfügung gestellt ?? – rball

Verwandte Themen