2013-03-05 9 views
5

Ho qualche codice javascript/jquery (per un sito Web interno) che esegue molta elaborazione lato client su un grande tavolo. Funziona un po 'lentamente, ma va bene.Come lasciare javascript "breath"

Il problema è che congela il browser mentre esegue i cicli che deve eseguire. Questo ha due effetti non desiderati:

  1. La filatrice elaborazione (un GIF animato, ma anche provato spin.js e che ha lo stesso problema) congela.
  2. Se ci sono abbastanza righe della tabella, i loop impiegano molto tempo e il browser riporta uno script che non risponde

C'è un modo per avere una sorta di una dichiarazione "respiro" nel codice, tale che ogni (diciamo) 100 iterazioni, si interrompe per far girare lo spinner e il browser sappia che lo script sta ancora lavorando su di esso? Qualcosa di simile (pseudo codice):

for (i=0;i<20000;i++) 
{ 
    fnProcessRow(); 
    if (i % 100 == 0) breath(); 
} 
+3

Sareste in grado di pubblicare il codice pertinente con cui si verificano problemi di prestazioni? Forse questo può essere prima ottimizzato prima di considerare altri costrutti artificiali "in attesa" –

+0

Sì, ma solo se si sta utilizzando una funzione autoesecutiva anziché un ciclo for. Puoi anche trasferirlo a un webworker nei browser che lo supportano. –

+0

è possibile eseguire una qualsiasi elaborazione sul server per alleggerire il carico sul front-end? – Evan

risposta

1

Un modo per rompere il vostro javascript è quello di dividere la trasformazione in blocchi e usare setTimeout() per eseguire il prossimo "chunk"

Fatemi sapere se avete bisogno un codice per mostrarti cosa intendo.

+0

sfortunatamente questo non è possibile in questa situazione in quanto non ho il controllo del codice di elaborazione per farlo, a meno che la dimensione del blocco sia 1 :) –

+0

Se non riesci a suddividere l'elaborazione in bit più piccoli, allora sei solo è usare i web worker. Ciò quindi non lo renderebbe compatibile con tutti i browser là fuori (al momento, comunque) –

1

Non esiste un metodo impostato per farlo poiché dipende in modo specifico dal codice. Qualcosa di simile potrebbe funzionare:

fnProcessRows(0, 10000); 

function fnProcessRows(start, end) { 
    /* do row processing */ 

    if (end < totalRows) { 
     setTimeout(function() { 
      fnProcessRows(start + 10000, end + 10000); 
     }, 1000); 
    } 
}); 

Questa elaborerà 10000 righe con un secondo di pausa in mezzo. Questo può avere effetti collaterali potenzialmente strani come la visualizzazione delle righe "elaborate" con righe "non elaborate", che possono essere indesiderabili. Se non lo è, allora questa dovrebbe essere una soluzione piuttosto semplice da aiutare.

Ovviamente è possibile ridurre 10000 a qualcos'altro se è non risponde, è non risponde; dovrebbe non rispondere per periodi di tempo molto brevi che l'utente avrebbe difficoltà a notare.

+0

Sfortunatamente (non chiaro dal mio esempio semplificato) l'elaborazione avviene tramite una richiamata che è anche fuori dal mio controllo, quindi non posso usare setTimeouts per elaborare in batch i callback. Potrei comunque usare un setTimeout per ogni chiamata, che potrebbe funzionare. –

0

Vedere this question.

Se non si vuole andare via setTimeout/setInterval, prova ad aggiungere:

if (i % 100) { $("selector for your animated image").width(); } 

Su alcuni (la maggior parte?) I browser che lo spingono a ri-layout e rendering.

Problemi correlati