5

Ich habe experimentiert mit Jank-freien Rendering von komplexen Szenen auf HTML5 Canvas. Die Idee besteht darin, das Rendern in mehrere Stapel zu unterteilen, wobei jeder Stapel maximal 12 ms dauert, damit die gleichzeitig laufenden Animationen (die sehr billig auszuführen sind) nicht unterbrochen werden.requestAnimationFrame kurz vor dem Ende des Frames aufgerufen?

Konzeptionell Batch-Rendering wird wie folgt umgesetzt:

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 
    } 
    }); 
} 

Der vollständige Code in diesem JSFiddle ist: https://jsfiddle.net/fkfnjrc2/5/. Der Code führt die folgenden Dinge aus:

  • Ändern Sie in jedem Frame die CSS-Transformationseigenschaft der Zeichenfläche (ein Beispiel für die gleichzeitig ausgeführte, schnell ausführbare Animation).
  • Initiieren Sie das Rendern in der Batch-Methode, wie oben gezeigt, von Zeit zu Zeit.
  • Leider sehe ich schreckliche Janks genau zu den Zeiten, wenn Canvas Inhalte neu gerendert werden. Was ich scheine nicht in der Lage sein, zu erklären, was die Chrome Developer Tools Timeline wie folgt aussehen:

    Janks in the Chrome Developer Tools timeline view

    Die ausgelassene Bilder scheinen durch die Tatsache verursacht werden, dass die requestAnimationFrame nicht gleich zu Beginn aufgerufen des Rahmens, aber gegen Ende der idealen 16ms-Periode. Wenn der Rückruf unmittelbar nach dem Abschluss des vorherigen Frame-Renderings gestartet wurde, würde der Code höchstwahrscheinlich rechtzeitig fertig gestellt sein.

    Rendern zu einem Offscreen Canvas (https://jsfiddle.net/fkfnjrc2/6/) und dann das vollständige Bild auf die Leinwand kopieren hilft ein wenig, aber die Janks sind immer noch mit genau den gleichen Eigenschaften (verzögerte Ausführung von rAF Callback).

    Was ist falsch an diesem Code? Oder stimmt etwas mit meinem Browser/Computer nicht? Ich sehe das gleiche Verhalten in Chrome (49.0.2623.112) unter Windows 10 und Mac OS.

    Antwort

    1

    Die Probleme scheinen von der spezifischen AnforderungsanalyseFrame-Rückrufplanung von Chrome verursacht zu werden. Ich habe eine bug abgelegt, um dies zu verfolgen, es enthält einige einfachere Reproduktion Code Beispiele.