2010-03-19 17 views
16

Tengo problemas con la velocidad de carga al utilizar múltiples jQuery binds en un par de miles de elementos y entradas, ¿hay alguna forma más eficiente de hacerlo?jQuery bind efficiency

El sitio tiene la capacidad de alternar entre las listas de productos a través de llamadas ajax, la página no se puede actualizar. Algunas listas tienen 10 elementos, unos 100, algunos más de 2000. El problema de la velocidad surge cuando comienzo a pasar de una lista a otra; cada vez que se carga la lista de más de 2000 elementos, el sistema se arrastra durante aproximadamente 10 segundos.

Antes de reconstruir la lista estoy configurando el html del elemento de destino como '' y desvinculando los dos enlaces a continuación. Estoy seguro de que tiene algo que ver con todas las llamadas principales, siguientes y secundarias que estoy haciendo en las devoluciones de llamada. Cualquier ayuda es muy apreciada.

bucle 2500 veces

<ul> 
    <li><input type="text" class="product-code" /></li> 
    <li>PROD-CODE</li> 
    ... 
    <li>PRICE</li> 
</ul> 

bucle final

$('li.product-code').bind('click', function(event){ 

    selector = '#p-'+ $(this).prev('li').children('input').attr('lm'); 

     $(selector).val(

      ($(selector).val() == '' ? 1 : (parseFloat($(selector).val()) + 1)) 

     ); 

    Remote.Cart.lastProduct = selector; 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).prev('li').children('input').attr('code'), 
       title  : $(this).next('li').html(), 
       quantity : $('#p-'+ $(this).prev('li').children('input').attr('lm')).val(), 
       price  : $(this).prev('li').children('input').attr('price'), 
       weight : $(this).prev('li').children('input').attr('weight'), 
       taxable : $(this).prev('li').children('input').attr('taxable'), 
       productId : $(this).prev('li').children('input').attr('productId'), 
       links  : $(this).prev('li').children('input').attr('productLinks') 
      }, 
      '#p-'+ $(this).prev('li').children('input').attr('lm'), 
      false, 
      (parseFloat($(selector).val()) - 1) 

    ); 

    return false; 

}); 

$('input.product-qty').bind('keyup', function(){ 

    Remote.Cart.lastProduct = '#p-'+ $(this).attr('lm'); 
    Remote.Cart.Products.Push( 

      Remote.Cart.customerKey, 
      { 
       code  : $(this).attr('code') , 
       title  : $(this).parent().next('li').next('li').html(), 
       quantity : $(this).val(), 
       price  : $(this).attr('price'), 
       weight : $(this).attr('weight'), 
       taxable : $(this).attr('taxable'), 
       productId : $(this).attr('productId'), 
       links  : $(this).attr('productLinks') 
      }, 
      '#p-'+ $(this).attr('lm'), 
      false, 
      previousValue 
    ); 
}); 

Respuesta

28

va a enlazar un controlador 2500 veces, en lugar de hacer uso de función ya sea en vivo o delegar esta manera:

$('li.product-code').live('click', function(event){ 
$('input.product-qty').live('keyup', function(){ 

.live() escuchas para el clic a burbujear en el nivel de DOM luego ejecuta el evento con el contexto de la fuente de clic Esto significa que tiene un controlador de eventos en lugar de 2500 de ellos, lo que significa que es mucho más rápido y más fácil en el navegador.

Si usted tiene un recipiente que envuelve el contenido sustituido que no está sustituido (se mantiene en todas las llamadas AJAX), puede hacer que sea más local como esto:

$('#container').delegate('li.product-code', 'click', function(event){ 
$('#container').delegate('input.product-qty', 'keyup', function(){ 

El resultado de esto es el caso burbujas menos veces antes de ser atrapado.

Otro punto de dolor es probablemente la creación de los elementos, ¿puedes publicar ese código? A menudo hay optimizaciones fáciles que producen un gran aumento de rendimiento allí.

actualización

A partir de jQuery 1.7, es obsoleto el método .live(). Use .on() para adjuntar controladores de eventos. Los usuarios de versiones anteriores de jQuery deben utilizar .delegate() con preferencia a .live() - JQuery Docs

+0

¡Vivo es el ganador! Ahora mi única interrupción de velocidad es un complemento sin clic derecho que descargué. Sin los enlaces, la creación de la lista fue instantánea, ahora es aproximadamente medio segundo. Con el script sin clic derecho se cuelga, pero eso se debe a las vinculaciones que imagino. ¡Muchas gracias! – clownshoes

+0

@chelfers - ¿Qué complemento sin clic derecho estás usando? Esto también debería ser bastante fácil de cambiar a '.live()' y obtener todo tu código al instante ... si no lo has hecho ya respondes aquí y voy a echar un vistazo. –

+0

'delegate()' es definitivamente el camino a seguir. Es mucho más óptimo que las alternativas cuando tienes miles de elementos de los eventos que deseas capturar. La única advertencia es que requiere jQuery 1.4. –

0

usted debe buscar en jqrid o flexigrid somthing que le permitirá hacer eso paginación adjudicar de datos a la salida a la vez por lo que es mejor para limite cuánto gasta de una vez, incluso si esas cosas son adecuadas para su proyecto, debe averiguar cómo limitar los datos en la línea de fondo

+0

El problema es que necesito todos los datos en una página en base a la petición del cliente. Ya he creado un sistema de paginación, pero no se utilizó -_- – clownshoes

2

Vincule su evento de clic a todo el documento, y dentro de la función, mire event.target para ver en qué elemento de producto se hizo clic realmente. De esta manera solo necesitas hacer un enlace único.

+0

Mejor tal vez para no vincularlo al documento completo, sino al elemento padre u ol primario. Definitivamente evitaría ir en vivo, ya que esto también tiene problemas de rendimiento, completamente evitables en este caso. – Jan

0

Primero, use el generador de perfiles integrado en Firebug para comprobar dónde está la mayor parte del retraso; simplemente pulse "perfil", ejecute su acción lenta, vuelva a golpear y vea qué llamadas son las más caras.

En segundo lugar, mira a la gestión de eventos "en vivo": http://api.jquery.com/live/

La forma en que esto funciona es que sólo hay un controlador de eventos, mirando a todo el documento, delegando a vivir controladores de eventos. Esto funciona mucho más rápido cuando tienes muchos elementos, porque no necesitas agregar un controlador de eventos específicamente para cada elemento.

+0

Fui con manejo en vivo. El generador de perfiles no me ayudó demasiado, ya que me dio una idea general de lo que ya sabía que estaba empantanando el script. – clownshoes