Unnötige Farben vermeiden – animierte GIF-Edition

Paul Lewis

Das Vermeiden von Malvorgängen ist entscheidend, um eine flüssige Framerate zu erzielen, insbesondere auf Mobilgeräten. Manchmal tauchen Farben jedoch an den ungewöhnlichsten Orten auf. In diesem Artikel erfahren Sie, warum animierte GIFs zu unnötigen Malaktionen führen können, und wie Sie das Problem ganz einfach beheben.

Schichten der Schönheit

Wie Sie wahrscheinlich wissen, können moderne Browser Gruppen von DOM-Elementen in separate „Bilder“ malen, die als Ebenen bezeichnet werden. Manchmal gibt es eine Ebene für die gesamte Seite, manchmal Hunderte oder in seltenen Fällen sogar Tausende.

Wenn DOM-Elemente in einer Ebene gruppiert sind und sich eines der Elemente visuell ändert, müssen wir nicht nur das geänderte Element, sondern auch alle anderen Elemente in der Ebene zeichnen, die sich mit dem geänderten Element überschneiden. Wenn Sie etwas über etwas anderes malen, sind die überschriebenen Pixel praktisch für immer „verloren“. Wenn Sie die ursprünglichen Pixel wiederherstellen möchten, müssen Sie sie neu malen.

Manchmal möchten wir also ein Element von den anderen isolieren, damit wir beim Malen nicht die anderen Elemente neu malen müssen, die sich nicht geändert haben. Wenn Sie beispielsweise einen fixen Seitenheader mit scrollbaren Inhalten kombinieren, müssen Sie den Header jedes Mal neu zeichnen, wenn der Inhalt gescrollt wird, sowie die neu sichtbaren Inhalte. Wenn Sie den Header in einer separaten Ebene platzieren, kann der Browser das Scrollen optimieren. Wenn Sie scrollen, kann der Browser die Ebenen verschieben – wahrscheinlich mithilfe der GPU – und das Neuzeichnen der Ebenen vermeiden.

Jede zusätzliche Ebene erhöht den Arbeitsspeicherverbrauch und den Leistungsaufwand. Daher sollten Sie die Seite in so wenige Ebenen wie möglich gruppieren, um eine gute Leistung zu erzielen.

Was hat das alles mit animierten GIFs zu tun?

Sehen wir uns dieses Bild an:

Eine Webanwendung, die in vier Schichten unterteilt ist.
Abbildung 1: Eine Webanwendung in vier Schichten

Dies ist eine mögliche Ebenenstruktur für eine einfache App. Es gibt hier vier Ebenen: Drei davon (Ebenen 2 bis 4) sind Benutzeroberflächenelemente; die hintere Ebene ist ein Ladebildschirm, der zufällig ein animiertes GIF ist. Im normalen Ablauf wird der Ladebildschirm (Ebene 1) angezeigt, während die App geladen wird. Sobald alles fertig ist, werden die anderen Ebenen angezeigt. Aber hier ist der Schlüssel: Sie müssen das animierte GIF ausblenden.

Aber warum muss ich es verstecken?!

Gute Frage. Im Idealfall würde der Browser die Sichtbarkeit des GIFs einfach für Sie prüfen und das automatische Zeichnen vermeiden. Leider ist es in der Regel teurer, zu prüfen, ob das animierte GIF verdeckt oder auf dem Bildschirm sichtbar ist, als es einfach zu übermalen. Daher wird es übermalt.

Im Idealfall befindet sich das GIF in einer eigenen Ebene und der Browser muss es nur auf die GPU malen und hochladen. Im schlimmsten Fall sind alle Elemente jedoch in einer einzigen Ebene gruppiert und der Browser muss jedes einzelne Element neu zeichnen. Und wenn sie fertig ist, muss sie noch alles auf die GPU hochladen. All diese Arbeit wird für jeden GIF-Frame ausgeführt, obwohl der Nutzer das GIF nicht einmal sehen kann.

Auf Desktop-Computern ist dieses Verhalten wahrscheinlich akzeptabel, da die CPUs und GPUs leistungsfähiger sind und es viel Bandbreite für die Datenübertragung zwischen den beiden gibt. Auf Mobilgeräten ist das Malen jedoch extrem teuer, Sie müssen also sehr vorsichtig sein.

Welche Browser sind davon betroffen?

Wie so oft unterscheiden sich die Verhaltensweisen zwischen den Browsern. Derzeit werden in Chrome, Safari und Opera alle Bilder neu gerendert, auch wenn das GIF verdeckt ist. Firefox erkennt hingegen, dass das GIF verdeckt ist und nicht neu gerendert werden muss. Der Internet Explorer ist nach wie vor eine Art Blackbox. Selbst in IE11 gibt es keine Hinweise darauf, ob eine Neumalerei stattfindet, da die F12-Tools noch in der Entwicklungsphase sind.

How can I tell if I have this problem?

Am einfachsten ist es, in den Chrome-Entwicklertools die Option „Zeichnen-Rechtecke anzeigen“ zu verwenden. Laden Sie die DevTools und klicken Sie rechts unten auf das Zahnradsymbol Zahnradsymbol. Wählen Sie dann unter Rendering die Option Paint rectangles show (Malquadrate anzeigen) aus.

„Zeichnen-Rechtecke anzeigen“ in den Chrome-Entwicklertools aktivieren
Abbildung 2: „Zeichnen-Rechtecke anzeigen“ in den Chrome-Entwicklertools aktivieren

Jetzt müssen Sie nur noch nach einem roten Rechteck suchen, das so aussieht:

Wenn in den DevTools unter „Zeichnen“ ein rotes Rechteck angezeigt wird, gibt es Probleme mit animierten GIFs.
Abbildung 3: Die Funktion „Zeichnen-Rechtecke anzeigen“ in den DevTools weist mit einem roten Rechteck auf Probleme mit animierten GIFs hin.

Das kleine rote Kästchen auf dem Bildschirm zeigt an, dass Chrome etwas neu anzeigt. Sie wissen, dass sich hinter den anderen Elementen ein GIF mit einem Ladebalken befindet. Wenn Sie also ein rotes Feld wie dieses sehen, müssen Sie die sichtbaren Elemente ausblenden und prüfen, ob das animierte GIF noch läuft. Wenn ja, müssen Sie CSS- oder JavaScript-Code einfügen, um display: none oder visibility: hidden auf das Element oder sein übergeordnetes Element anzuwenden. Wenn es sich nur um ein Hintergrundbild handelt, sollten Sie es natürlich entfernen.

Ein Beispiel für dieses Verhalten auf einer Live-Website finden Sie auf Allegro. Dort ist das Bild jedes Produkts mit einem Ladebalken versehen, der nur unkenntlich gemacht, aber nicht explizit ausgeblendet wird.

Fazit

Um 60 fps zu erreichen, muss nur das getan werden, was zum Rendern der Seite erforderlich ist. Das Entfernen von überschüssiger Farbe ist ein wichtiger Schritt, um dieses Ziel zu erreichen. Animierte GIFs, die laufen gelassen werden, können unnötige Zeichnaktionen auslösen. Mit dem Tool „Zeichnen-Rechtecke anzeigen“ in den DevTools können Sie diese leicht finden und beheben.

Sie haben das animierte GIF mit dem Kätzchen, das den Ladevorgang begleitet, doch nicht ewig laufen lassen, oder?