2009-04-13 11 views
5

Dado que uso jQuery 1.3+ todos excepto uno de los exámenes cronometrados lo estoy usando. La otra es simple javascript que encontré desde atrás en el 2000. Dejé de seguir esa ruta ya que me tomó alrededor de 150 segundos ejecutar la prueba. He leído bastantes páginas web de optimización jQuery relacionadas con la selección de un solo elemento. Un '#id' es el mejor caso para usar eso, pero ahora tengo el problema de marcando todas las casillas de verificación en una columna en una tabla bastante grande que tiene múltiples columnas de casilla de verificación.¿Cuál es la forma más rápida de seleccionar una gran cantidad de casillas de verificación y de seleccionarlas?

Lo que he hecho es una configuración de la página crea 20.000 filas de la tabla con dos columnas de casilla de verificación. El objetivo es verificar la segunda columna para ver cuánto tiempo tomó, y luego desmarcarlos y ver cuánto tiempo tomó. Obviamente, queremos el tiempo más bajo. Solo uso IE6 y 7 y en mi caso todos mis usuarios harán lo mismo.

20.000 filas que usted dice? Eso es lo que dije también, pero esto va a la producción (fuera de mi alcance) y es demasiado tarde para cambiar ahora. Estoy tratando de lanzar un granizo con 1 segundo restante en el reloj. Además, aprendí que input.chkbox no es el selector más rápido (para IE7). :)

La pregunta es, ¿hay una mejor manera de hacer esto jQuery o de otra manera? Me encantaría que se ejecutara en menos de medio segundo en mi máquina.

Así que usted no tiene que volver a escribir toda la basura que ya he hecho aquí es el material de prueba que se me ocurrió:

Actualizado mañana 4/14 a incluir, además, pruebas de tiempo:

<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

No me refiero a ser inútil, pero 20k filas en una página es simplemente un mal diseño. Deberías arreglar ESO. :) –

+0

Bueno ... no es broma. :) ¡No lo hice! En este momento no hay tiempo suficiente para arreglarlo para este lanzamiento. Será lo primero que debe hacer en la próxima versión. Sin embargo, este proyecto ha planteado muchos desafíos "interesantes" hasta el momento. – rball

Respuesta

8

entrada [name = chkbox] viene como el selector jQuery más rápido en mi máquina bajo IE7.

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

input.chkbox y ...

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

de entrada: checkbox.chkbox parecen atado

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

.chkbox casi se lleva el doble de tiempo que el input.chkbox

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

El javascript para el bucle es de lejos el peor llegando a:

Checking Took 149797ms 

150 cuestión de segundos! También bloquea el navegador. Esto me impresionó mucho con jQuery. Honestamente, no esperaba que fuera tan lento. Probablemente porque estoy pasando por cada elemento individual que luego tiene que encontrar ...

Esto fue bastante interesante para mí también:

de entrada [id^= 'chkbox']

Unchecking Took 3031ms 
Checking Took 3016ms 

tomó menos tiempo que:

de entrada [id^= 'chkbox'] [type = 'checkbox']

Unchecking Took 3375ms 
Checking Took 3344ms 

Pensé que ya que había publicado más filtros sería más rápido. ¡No!

Especificación incluso más caminos a la casilla de verificación hace manera más lenta:

#myTable tr [id^= 'fila'] de entrada [id^= 'chkbox'] [type = 'casilla de verificación']

Checking Took 10422ms 

Ni siquiera se ejecutó la segunda desmarcar, ya que me preguntó si quería seguir ejecutando secuencias de comandos en mi computadora. ¡Loca! : P

actualización de la mañana 4/14:

Alguien trajo hasta establecer el contexto: en realidad lo hice algunas de esas y para mi gran sorpresa y en contra de lo que mucha gente ha dicho en la web en IE7 estos fueron más lentos! Estos son los tiempos que obtuve con especificada emparejado con el selector de arriba más rápido de unos pocos contexto diferente: tr

"input.chkbox", "tr"

Checking Took 8546ms 

"input.chkbox"," .myRow"

Checking Took 8875ms 

"input.chkbox", "# formulario1"

Unchecking Took 3032ms 
Checking Took 3000ms 

"input.chkbox", "#myTable"

Unchecking Took 2906ms 
Checking Took 2875ms 

Ganador actual (todavía): entrada [name = chkbox]

Unchecking Took 2469ms 
Checking Took 2453ms 

"de entrada [nombre = 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 

Actualización 2 Mañana 4/14

Pensé que podría haber tenido una mejor después de notar una diferencia de sintaxis de http://beardscratchers.com/journal/jquery-its-all-about-context. Parece que estos NO son los mismos que que están dando tiempos ligeramente mejores, pero aún no supera al selector sin contexto - maldición.

"de entrada [name = chkbox]", $ ("# Form1")

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

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

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

actualización 3 de la mañana 4/14

Russ me quería probar estos, que es/seleccionar todos los bo equis pero de nuevo fue interesante:

: casilla

Unchecking Took 8328ms 
Checking Took 6250ms 

de entrada: casilla

Unchecking Took 5016ms 
Checking Took 5000ms 

-> más rápido?!?! entrada [type = casilla]

Unchecking Took 4969ms 
Checking Took 4938ms 

El hecho de que la tercera allá arriba es el más rápido es bastante interesante, ya que va en contra de lo que hubiera pensado. ¿Por qué no (al menos para IE7) la casilla de verificación: use simplemente la casilla de verificación tipo = para lograr un tiempo más rápido? Estos son puntajes muy cercanos, pero la verificación tomó 62 ms menos tiempo. Además, ¿por qué los dos primeros son diferentes en absoluto? ¿Hay algún elemento diferente además de una entrada que pueda tener una casilla de verificación?

+0

Más criterios de selección no aceleran una consulta a menos que cada uno reduzca el tamaño del conjunto. Como todas las casillas de verificación están en filas de tablas y tienen entrada, agregarlas como criterios no ayuda. –

+0

"Pensé que ya que publiqué más filtros sería más rápido". como dijo Zan, más filtros = más controles = más procesamiento = más tiempo. A menos que cada filtro reduzca significativamente el tamaño del conjunto para el siguiente filtro, solo está tomando ciclos. – nickf

5

no he probado esto, pero usted podría intentar la construcción de una matriz [] de referencias casilla de verificación en la página de carga luego simplemente iterar sobre que cada vez que desee hacer un cambio?

Pagaría el costo de rendimiento en la carga de la página, pero podría ser más rápido que caminar el DOM cada vez. Oye, al menos realizarías el trabajo pesado en el "tiempo de inactividad" del usuario (cuánto tiempo tarda la gente en localizarlo y hacer clic en las opciones de deselección/selección).

+0

O me pregunto si podría "almacenarlos en caché" en una matriz la primera vez (o en la carga), y luego sería más rápido cuando lo golpeen de nuevo. Buena idea, lo intentaré. – rball

+0

¡déjame saber cómo te va! – Codebrain

+0

Lo hará, pero podría ser mañana, ya que el día de trabajo casi ha terminado. – rball

2

Mi única sugerencia probablemente tampoco funcionará. Cambia los navegadores. Pero solo he tenido una empresa que realmente está de acuerdo con eso. Hicimos que la empresa cambiara a Firefox y usuarios específicos se mudaron a Google Chrome. IE es demasiado lento con JavaScript.

Además, puede intentar precapturar la lista de consultas de jquery.

Si todo lo demás falla, resuélvelo con psicología. Eso significa que el usuario debe saber que algo llevará mucho tiempo. Coloque un div "Please wait" mientras la función está funcionando. De esta forma, el usuario sabe que el navegador no solo está bloqueado y sabe cuándo puede volver a funcionar. He tenido muchas páginas lentas "resueltas" al hacer esto.

+0

jaja, sí solo no va a suceder. Tengo la "suerte" de poder usar IE7. Todos los demás deben usar IE6. Voy a ver el precaching. – rball

+0

Otra opción ... Está utilizando la manipulación de los atributos JQuery para establecer checked: $ (selectorText) .attr ("checked", false); También podría probar $ (selectorText) .each (function() {this.checked = false}); Sin garantías, pero podría valer la pena intentarlo. –

+0

Pensado en hacer eso. Lo probaré y veré qué pasa. De hecho, estamos poniendo una notificación de por favor espere, antes de que fuera 150 segundos, pero bajar a 2-3 será excelente. – rball

1

¿Ha probado los selectores jQuery con context para ver si eso mejora el rendimiento? Presumiblemente, los controles estarán dentro de un formulario ASP.NET, y tal vez otro elemento identificable de forma única.

Por ejemplo, cuando usted tiene

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

intento con

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

Here's a BeardScratchers article el contexto

EDIT:

Siguiendo sus actualizaciones, parece que 2.45- 6 segundos podría ser el más rápido que puedas lograr, dadas tus circunstancias.

Para completar, ¿ha probado los siguientes selectores?

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

Parece ser más lento. Tal vez aún no he obtenido el contexto "correcto" ... – rball

+0

Publicación actualizada con resultados. – rball

+0

Espera ... leer artículo completo, parece que he estado proporcionando el contexto incorrecto ?? – rball

Cuestiones relacionadas