5

Ho sperimentato con il rendering senza jank di scene complesse su tela HTML5. L'idea è di dividere il rendering in più lotti con ciascun batch, con un massimo di, diciamo 12 ms, in modo che le animazioni in esecuzione simultanea (molto economiche da eseguire) non vengano interrotte.requestAnimationFrame chiamato proprio prima della fine del frame?

Concettualmente, lotto rendering è implementata in questo modo:

function draw(ctx) { 
    var deadline = window.performance.now() + 12; // inaccurate, but enough for the example 
    var i = 0; 
    requestAnimationFrame(function drawWithDeadline() { 
    for (; i < itemsToRender.length; i++) { 
     if (window.performance.now() >= deadline) { 
     requestAnimationFrame(drawWithDeadline); 
     return; 
     } 

     var item = itemsToDraw[i]; 
     // Draw item 
    } 
    }); 
} 

Il codice completo è in questo JSFiddle: https://jsfiddle.net/fkfnjrc2/5/. Il codice esegue le seguenti operazioni:

  • Su ogni frame, modificare la proprietà di trasformazione CSS dell'area di disegno (che è un esempio dell'animazione di esecuzione veloce in esecuzione simultanea).
  • Una volta ogni tanto, avviare il re-rendering della tela nel modo batch come mostrato sopra.

Sfortunatamente, sto vedendo orribili janks esattamente nel momento in cui il contenuto della tela viene ri-renderizzato. Quello che non mi sembra di essere in grado di spiegare che cosa è il Chrome Developer Tools linea temporale appare come:

Janks in the Chrome Developer Tools timeline view

La perdita di frame sembrano essere causato dal fatto che il requestAnimationFrame non si chiama proprio all'inizio del telaio, ma verso la fine del periodo ideale di 16ms. Se la callback è iniziata subito dopo il rendering del frame precedente, il codice verrebbe probabilmente completato in tempo.

Il rendering su una tela fuori schermo (https://jsfiddle.net/fkfnjrc2/6/) e quindi copiare l'immagine completa sulla tela dello schermo aiuta un po ', ma i janks sono ancora lì con esattamente le stesse caratteristiche (esecuzione ritardata della richiamata rAF).

Cosa c'è di sbagliato con quel codice? O forse qualcosa non va con il mio browser/macchina? Sto riscontrando lo stesso comportamento su Chrome (49.0.2623.112) su Windows 10 e Mac OS.

risposta

1

I problemi sembrano essere causati dalla specifica richiesta di ChromeAnimationFrame callback scheduling. Ho archiviato uno bug per tracciare questo, contiene alcuni esempi di codice di riproduzione più semplici.