2010-03-19 11 views
16

Ho riscontrato problemi con la velocità di caricamento utilizzando più collegamenti jQuery su un paio di migliaia di elementi e input, esiste un modo più efficiente per farlo?jQuery bind efficiency

Il sito ha la possibilità di passare da un elenco di prodotti tramite chiamate Ajax, la pagina non può essere aggiornata. Alcune liste hanno 10 articoli, circa 100, alcuni nel 2000. La questione della velocità si verifica quando inizio a sfogliare le liste; ogni volta che viene caricato l'elenco di articoli 2000+, il sistema si trascina per circa 10 secondi.

Prima di ricostruire l'elenco, ho impostato l'html dell'elemento di destinazione su "" e lo sbiadimento dei due collegamenti di seguito. Sono sicuro che ha qualcosa a che fare con tutte le chiamate parent, next e child che sto facendo nei callback. Ogni aiuto è molto apprezzato.

ciclo 2500 volte

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

anello fine

$('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 
    ); 
}); 

risposta

28

si sono vincolanti un gestore di 2500 volte, invece rendere l'uso del funzionamento dal vivo o delegare in questo modo:

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

.live() ascolti per il clic a ribollire a livello DOM poi esegue l'evento con il contesto della sorgente di clic. Questo significa che hai un un gestore di eventi invece di 2500 di essi, il che significa che è molto più veloce e più facile sul browser del.

Se si dispone di un contenitore che avvolge il contenuto sostituito che non viene sostituito (rimane in tutte le chiamate AJAX), si può rendere più locale come questo:

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

Il risultato di questo è l'evento bolle meno volte prima di essere catturato.

Un altro punto dolente è probabilmente la creazione degli elementi, puoi pubblicare quel codice? Ci sono spesso ottimizzazioni facili che danno un grande incremento di prestazioni lì.

Aggiornamento

Come di jQuery 1.7, il metodo .live() è deprecato. Utilizzare .on() per allegare gestori di eventi. Gli utenti di vecchie versioni di jQuery dovrebbero usare .delegate() a preferenza di .live() - JQuery Docs

+0

Il live è il vincitore! Ora il mio unico blocco di velocità è un plug-in senza clic con il tasto destro del mouse che ho scaricato. Senza le associazioni la creazione della lista è stata istantanea, ora è di circa mezzo secondo. Con lo script no-right-click si blocca, ma ciò è dovuto ai vincoli che immagino. Molte grazie! – clownshoes

+0

@chelfers - Quale plug-in senza clic destro usi? Questo dovrebbe anche essere abbastanza facile da passare a '.live()' e ottenere tutto il tuo codice istantaneo ... se non lo hai già fatto, rispondi qui e darò un'occhiata. –

+0

'delegate()' è sicuramente la strada da percorrere. È molto più ottimale delle alternative quando hai migliaia di elementi di quali eventi desideri catturare. L'unica avvertenza è che richiede jQuery 1.4. –

0

si dovrebbe guardare a jqrid o flexigrid somthing che vi permetterà di fare questo è di paging assegnare di dati per l'output in una volta quindi è meglio Limita quanto spendi subito anche se queste cose sono giuste per il tuo progetto devi capire come limitare i dati è la linea di fondo

+0

Il problema è che ho bisogno di tutti i dati in un'unica pagina basate su richiesta del cliente. Ho già creato un sistema di paging, ma è andato inutilizzato -_- – clownshoes

2

Associare l'evento click all'intero documento e all'interno della funzione, guardare event.target per vedere su quale elemento prodotto è stato effettivamente fatto clic. In questo modo devi solo eseguire un singolo bind.

+0

Meglio forse non legarlo a tutto il documento, ma all'elemento padre ul ol. Eviterei sicuramente di andare in diretta, visto che questo ha anche problemi di prestazioni, completamente evitabili in questo caso. – Jan

0

Innanzitutto, utilizzare il profiler incorporato in Firebug per verificare dove si trova la maggior parte del ritardo; basta premere "profilo", eseguire la tua azione lenta, colpire di nuovo e vedere quali sono le chiamate più costose.

secondo luogo, guardare la gestione degli eventi "live": http://api.jquery.com/live/

Il modo in cui funziona è che c'è solo un gestore di eventi, guardando l'intero documento, delegando a vivere gestori di eventi. Funziona molto più velocemente quando hai un sacco di elementi, perché non hai bisogno di aggiungere un gestore di eventi a ogni elemento in particolare.

+0

Sono andato con la gestione dal vivo. Il profiler non mi ha aiutato troppo perché mi ha dato un senso generale di ciò che già sapevo stava mettendo a tacere la sceneggiatura. – clownshoes