Browser hatten jahrelang versucht, flüssiger zu werden, indem sie weniger taten: nur geänderte Rechtecke invalidieren, Teile als Layer cachen, diese komponieren und schließlich beide Aufgaben auf die GPU verlagern. Auf Mozilla Hacks erklärte Lin Clark im Oktober 2017, warum Seiten trotzdem noch ruckelten. Layer kosten Speicher und Übertragungszeit, und Browser müssen raten, wie viele eine Seite braucht. Zu viele Layer füllen den Speicher und bremsen den Compositor; zu wenige bedeuten, dass ein neu gezeichneter Layer komponiert wird, ohne dass sich etwas geändert hat, wodurch jeder Pixel zweimal angefasst wird. Das Animieren einer Hintergrundfarbe erzwingt unabhängig davon eine Neuzeichnung des gesamten Layers.

WebRender, Servo-Technologie, die als Quantum Render in Firefox Einzug hielt, folgte einem anderen Vorbild: 3D-Game-Engines zeichnen jeden Pixel jedes Frames neu und halten 60 FPS zuverlässiger als Browser, auf GPUs mit Hunderten oder Tausenden von Kernen, die Pixel parallel shaden. WebRender hob also die Grenze zwischen Paint und Composite auf. Die Layout-Ausgabe wurde zu einer Display-Liste aus High-Level-Zeichenanweisungen, die an keine Grafik-API gebunden sind. Der RenderBackend von WebRender wandelte diese Liste in gebündelte GPU-Draw-Calls um, und die GPU zeichnete jedes Frame die gesamte sichtbare Szene der Seite neu, ohne Layer-Raterei.

Um das Neuzeichnen ganzer Frames bezahlbar zu machen, musste Arbeit eliminiert werden. Off-Screen-Elemente wurden aussortiert, bevor sie die GPU erreichten. Ein Render-Task-Baum plante die minimale Anzahl teurer Offscreen-Texturen für Filter und Stacking-Kontexte. Draw-Calls wurden gebündelt, um die parallelen Kerne der GPU auszulasten. Das Rendering wurde in einen opaken Front-to-Back-Pass, der verdeckte Pixel übersprang, und einen transluzenten Back-to-Front-Pass aufgeteilt – Z-Culling, so der Artikel, und ein großer Gewinn auf typischen Seiten. Textglyphen blieben eine CPU-Aufgabe, wurden aber in einer Textur gecacht, die von Frame zu Frame erhalten blieb.

Das Ziel war Konsistenz, nicht nur Geschwindigkeit: keine Performance-Klippen, flüssige 60 FPS, egal wie groß das Display oder wie viel der Seite sich ändert. Der Artikel berichtete, dass Seiten, die in Chrome oder im damaligen Firefox mit 15 FPS vor sich hinruckelten, mit WebRender mit 60 FPS liefen, und rahmte die Arbeit als Vorbereitung auf 4K-Displays und auf WebVR ein, das ein Frame für jedes Auge mit 90 FPS rendert.

Schluss mit Layer-Raterei: der GPU eine High-Level-Display-Liste übergeben und die ganze Seite jedes Frame neu zeichnen, im Stil einer Game-Engine

GPUs haben Hunderte bis Tausende von Kernen, die Pixel parallel shaden, sodass das Neuzeichnen der gesamten sichtbaren Seite jedes Frame genau die Arbeitslast ist, für die sie gebaut wurden, und keine Aufgabe in CPU-Größenordnung.

Eine beibehaltene Display-Liste ist eine kleine, API-agnostische Beschreibung der Szene, sodass die CPU Befehle einmal aufbaut und der RenderBackend sie aussortieren, ordnen und bündeln kann, bevor irgendeine Pixelarbeit stattfindet.

Das Neuzeichnen der gesamten Szene beseitigt die Layer-Raterei und ihre Fehlermodi: keine falsch eingeschätzten Layer-Zahlen, keine doppelte Behandlung von Pixeln, sodass Frame-Zeiten nicht mehr von Performance-Klippen abstürzen.

Arbeitseliminierung hält das Neuzeichnen günstig: Culling, weniger Offscreen-Ziele, Batching und Z-Culling verkleinern, was die GPU shadet, während CPU-gerenderte Glyphen in einem Textur-Cache leben, nicht im Pro-Frame-Pfad.

Wenn inkrementelle Heuristiken immer wieder auf Worst-Case-Klippen stoßen, ändere das Modell: beschreibe die gesamte Szene einmal und lass massiv parallele Hardware sie jedes Frame neu zeichnen

WebRender war nicht in der Firefox-Quantum-Version enthalten, die darauf folgte: Lin Clark schrieb in den Kommentaren des Artikels, dass es erst nach Firefox 57 landen würde, und der Beitrag plante die Integration bis 2018 im Rahmen des Projekts Quantum Render, wobei eine frühe Version bereits hinter einem Flag verfügbar war. Die Demo, auf die er verlinkte, zeigte Seiten, die in Chrome oder im damaligen Firefox mit 15 FPS liefen und mit WebRender mit 60 FPS liefen, und der Erklärartikel erhielt am 10. Oktober 2017 auf Hacker News 853 Punkte und 207 Kommentare.

DEN BELEGEN FOLGEN

Die Quellen

  1. The whole web at maximum FPS: How WebRender gets rid of jank Mozilla Hacks · hacks.mozilla.org ·
  2. Hacker News discussion: The whole web at maximum FPS — How WebRender gets rid of jank Hacker News · news.ycombinator.com ·