WebGL-Performance

WebGL hat einen schlechten Ruf: Entwickler gehen davon aus, dass WebGL langsam ist und keine komplexen 3D-Grafiken rendern kann. Viele Beispiele zeigen, dass dies nicht wahr ist, dennoch verstärkt die Erfahrung der Entwickler immer wieder diese Annahme.

Die Hardware, die WebGL-Code ausführt, wird für Browser nicht gedrosselt. Warum also glauben Entwickler, dass es unmöglich ist, schnelle 3D-Grafiken im Web zu rendern?

Dieser Artikel wird Dich durch die WebGL-Performance führen und zeigen, wie auch Du schnelles 3D-Rendering im Web erreichen kannst.

CPU vs GPU 

In einer 3D-Anwendung läuft ein Teil des Codes auf der CPU und ein Teil auf beschleunigter Hardware, der GPU.

WebGL ist so konzipiert, dass es die Nutzung der GPU zur Beschleunigung von Grafik-Anwendungen im Web ermöglicht. WebGL kann daher als Funktionen verstanden werden, die Arbeit an die Grafikhardware senden und das Ergebnis abrufen.

Der Code, der die Arbeit für die GPU erstellt, läuft auf der CPU und wir steuern ihn über JavaScript.

Browser-Overhead 

Da ein Ziel des Browsers darin besteht, den Benutzer vor potenziell bösartigen Websites zu schützen, wird er die Sicherheit jeder WebGL-Anfrage, die die Website über JavaScript macht, überprüfen. Er muss auch den Prozess isolieren, der den Code der Website ausführt, und alle Anfragen zu und von diesem Prozess müssen in ein sendbares Format umgewandelt werden, das “Marshalling” genannt wird.

Sowohl das Marshalling als auch die Überprüfung der WebGL-Anfragen der Website erfordern Arbeit, die einen Performance-Kosten verursacht, verglichen mit der gleichen Anfrage in einer nativen Umgebung.

WebGL-Anfragen vermeiden 

Um WebGL-Performance zu erreichen, sollten wir daher Anfragen vermeiden, die eine hohe Kosten verursachen. Du wirst leicht herausfinden, welche Anfragen besonders teuer sind, indem Du Deine WebGL-Anwendung profilierst.

Folgende Anfragen sind kontraintuitiv teuer:

Eine hervorragende Möglichkeit, diese Anfragen zu vermeiden, ist das WebGL-Zustandstracking und die Reduzierung der Fehlerüberprüfung in Produktions-Builds Deiner WebGL-Anwendung.

Draw Calls vermeiden 

Das Geheimnis für exzellente WebGL-Performance besteht jedoch darin, so wenige Draw Calls wie möglich zu haben. Ein Draw Call ist jede Funktion, die eine der folgenden WebGL-Funktionen verwendet:

Es gibt viele Möglichkeiten, dies zu erreichen. Beispielsweise durch die Nutzung eines Funktionsaufrufs, der viele Objekte zeichnet, anstatt eine Funktion mehrmals aufzurufen, um dieselben Objekte zu zeichnen. Du kannst Instancing verwenden, um eine große Anzahl des gleichen Meshs zu rendern, oder WEBGL_multi_draw nutzen, um viele verschiedene Objekte mit dem gleichen Shader zu rendern.

3D-Engines haben oft eine Funktion namens “Batching”, die viele Aufrufe zu einem einzigen WebGL-Aufruf zusammenführt. Wonderland Engine treibt dies auf die Spitze, indem Szenen mit zehntausenden dynamischen Objekten in weniger als zehn Draw Calls automatisch gerendert werden.

Die WebGL-Performance auf Mobilgeräten wird besonders durch Draw Calls beeinflusst.

WebGL auf Safari 

Auf Safari (sowohl iOS als auch macOS) gibt es zusätzliche WebGL-Anfragen, die mit überraschend hohen Overheadkosten verbunden sind, zum Beispiel:

Achte besonders auf die Verwendung von Uniform Buffers, wenn Du für Safari optimierst.

JavaScript 

Die Sprache, die zur Schnittstelle mit Browser-APIs, wie WebGL, verwendet wird, ist JavaScript. Der Hauptschuldige für Performanceprobleme mit JavaScript ist die Garbage Collection, die automatisch Speicher identifiziert und entfernt, der nicht mehr benötigt wird.

Der Garbage Collection-Prozess kann die Performance von WebGL-Anwendungen unvorhersehbar und unzuverlässig machen, da man keine Kontrolle darüber hat, wann er auftritt. Dadurch kann es oft zu Zeiten angewendet werden, in denen es zu Stottern im Rendering kommt, was den Anschein schlechter Performance erweckt, selbst wenn der Code ansonsten gut optimiert ist.

Um stabile Bildraten zu erzielen, nimm eine strikte Herangehensweise beim Schreiben von müllfreiem JavaScript an.

iOS Safari und Speicher 

WebGL-Apps, die gut in Safari laufen, sind selten. Die WebGL-Performance auf Safari bringt einige zusätzliche Herausforderungen mit sich. Wir haben einen ganzen Blog-Post darüber geschrieben, wie man für Safari optimiert.

Speichergrenzen 

Auf iOS hast Du noch eine weitere Herausforderung: Die Browser-Tabs haben sehr begrenzten Speicher, insbesondere auf älterer iPhone-Hardware. Wenn Du die Speichergrenzen überschreitest, kann es sein, dass sich der Tab neu lädt oder einfriert. Da iPhones einen gemeinsamen Speicher nutzen, wird RAM für CPU und GPU geteilt und sowohl Textur- als auch Pufferdaten sowie JavaScript- oder WebAssembly-Speicher zählen zum Limit.