Domanda

Ho creato uno script che sbiadisce il colore di sfondo di un elemento. Uso setTimeout () per apportare una modifica incrementale al colore ogni 5 ms. La sceneggiatura funziona alla grande se sto solo sbiadendo il colore di sfondo di una cosa alla volta, ma se ho, diciamo, 50 elementi che sto sbiadendo tutti in una volta, la velocità è molto più lenta di 5 ms a causa di tutto i setTimeout () simultanei sono in esecuzione contemporaneamente. Una dissolvenza che normalmente dovrebbe essere eseguita in 1 secondo, ad esempio, potrebbe richiedere 30 secondi se sto dissolvendo 50 elementi contemporaneamente.

Qualche idea su come posso superare questo?

Ecco lo script nel caso in cui qualcuno abbia delle idee:

function fadeBackground(elementId, start, end, time) {
    var iterations = Math.round(time / 5);

    var step = new Array(3);

    step[0] = (end[0] - start[0]) / iterations;
    step[1] = (end[1] - start[1]) / iterations;
    step[2] = (end[2] - start[2]) / iterations;

    stepFade(elementId, start, step, end, iterations);
}

function stepFade(elementId, cur, step, end, iterationsLeft) {
    iterationsLeft--;

    document.getElementById(elementId).style.backgroundColor
        = "rgb(" + cur[0] + "," + cur[1] + "," + cur[2] + ")";

    cur[0] = Math.round(end[0] - step[0] * iterationsLeft);
    cur[1] = Math.round(end[1] - step[1] * iterationsLeft);
    cur[2] = Math.round(end[2] - step[2] * iterationsLeft);

    if (iterationsLeft > 1) {
        setTimeout(function() {
            stepFade(elementId, cur, step, end, iterationsLeft);
        }, 5);
    }
    else {
        document.getElementById(elementId).style.backgroundColor 
            = "rgb(" + end[0] + "," + end[1] + "," + end[2] + ")";
    }
}

È usato così:

fadeBackground("myList", [98,180,232], [255,255,255], 1000);
È stato utile?

Soluzione

Ecco un articolo da Google, dove l'autore discute del proprio lavoro sui timer per Gmail. Hanno scoperto che avere un singolo timer ad alta frequenza era più veloce rispetto all'utilizzo di più timer se avevano un utilizzo pesante e rapido del timer.

Potresti avere un timer che si attiva ogni 5 ms e aggiungere tutti i tuoi elementi che devono essere sbiaditi in una struttura di dati che tiene traccia di dove si trovano nel processo di dissolvenza. Quindi il tuo unico timer può consultare l'elenco ed eseguire la dissolvenza successiva per ogni elemento ogni volta che viene attivato.

D'altra parte, hai provato a utilizzare una libreria come Mootools o JQuery anziché creare il tuo framework di animazione? I loro sviluppatori hanno lavorato molto per ottimizzare questo tipo di operazioni.

Altri suggerimenti

Prima di tutto il tuo script non tiene conto del fatto che il timeout minimo è di solito 10-15ms a seconda del browser. Puoi vedere il mio post su questo argomento . All'interno troverai una tabella per i browser più diffusi e un link al programma che lo misura, in modo da poter verificare tu stesso il reclamo. Mi dispiace dirlo, ma iterazioni ogni 5 ms sono un pio desiderio.

In secondo luogo, i timer non sono interruzioni. Non c'è magia in loro: non possono interrompere ciò che è in esecuzione nel browser ed eseguire il loro payload. Verranno invece posticipati fino al termine del codice in esecuzione e il browser riprenderà il controllo e la possibilità di eseguire i timer. Lo sbiadimento di 50 elementi richiede tempo e scommetto che è più di 5 ms, soprattutto se si tiene conto dell'intero modello differito del browser: si aggiorna DOM e il browser aggiornerà la sua rappresentazione visiva ... a un certo punto nel tempo.

Voglio finire con una nota positiva:

  • Invece di sbiadire 50 singoli elementi, prova a raggrupparli e a sbiadire i loro genitori - può essere più veloce.
  • Sii più creativo nell'interfaccia utente. Prova a trovare una soluzione, che non richiede lo sbiadimento di molti elementi indipendenti contemporaneamente.
  • Verifica sempre che i tuoi presupposti di background siano corretti prima di progettarli intorno.
  • Se puoi, prova a scegliere come target i browser moderni. Dalla mia esperienza personale, Google Chrome è molto bravo con i timer e il suo motore JavaScript (V8) è estremamente veloce.

Oltre alle altre risposte, ecco un eccellente articolo di John Resig sui timer: http://ejohn.org/blog/how-javascript-timers-work/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top