Performance-Showdown für Web-Bildeffekte

Veröffentlicht: 2022-03-10
Kurze Zusammenfassung ↬ Da Browser ihre grafischen Wiedergabefähigkeiten ständig verbessern, wird die Möglichkeit, wirklich in ihnen zu entwerfen, immer mehr zur Realität. Ein paar Codezeilen können jetzt eine schnelle und dramatische visuelle Wirkung haben und Konsistenz ohne großen Aufwand ermöglichen . Und wie bei den meisten Dingen in der Webentwicklung gibt es oft viele Möglichkeiten, den gleichen Effekt zu erzielen. In diesem Beitrag werfen wir einen Blick auf einen der beliebtesten Bildeffekte, Graustufen, und bewerten sowohl die einfache Implementierung als auch die Auswirkungen auf die Leistung von HTML-Canvas, SVG, CSS-Filtern und CSS-Mischmodi. Welcher wird gewinnen?

Da Browser ihre grafischen Wiedergabefähigkeiten ständig verbessern, wird die Fähigkeit, in ihnen wirklich zu entwerfen, immer mehr zur Realität. Ein paar Codezeilen können jetzt eine schnelle und dramatische visuelle Wirkung haben und Konsistenz ohne großen Aufwand ermöglichen . Und wie bei den meisten Dingen in der Webentwicklung gibt es oft viele Möglichkeiten, den gleichen Effekt zu erzielen.

In diesem Beitrag werfen wir einen Blick auf einen der beliebtesten Bildeffekte, Graustufen, und bewerten sowohl die einfache Implementierung als auch die Auswirkungen auf die Leistung von HTML-Canvas, SVG, CSS-Filtern und CSS-Mischmodi. Welcher wird gewinnen?

Weiterführende Literatur zu SmashingMag:

  • Performance-Showdown für Web-Bildeffekte
  • HTML5: Die Fakten und die Mythen
  • Effiziente Größenanpassung von Bildern mit ImageMagick
  • Clevere JPEG-Optimierungstechniken

Filter im Web funktionieren wie eine Linse, die über ein Bild gelegt wird. Sie werden auf das Bild angewendet, nachdem der Browser das Layout und die anfängliche Farbe gerendert hat. In unterstützenden Browsern können Filter einzeln angewendet oder übereinander geschichtet werden. Da sie nach dem anfänglichen Rendern als Bildänderungen angewendet werden können und wahrscheinlich eine Verbesserung darstellen, werden Filter elegant degradiert, indem sie in Browsern, die sie nicht unterstützen, einfach nicht sichtbar sind.

Mehr nach dem Sprung! Lesen Sie unten weiter ↓

CSS-Filter

Beginnen wir mit der einfachsten Methode zur Erzeugung eines Graustufeneffekts: dem bescheidenen, aber leistungsstarken CSS-Filter.

ungefiltertes Vogelbild
Ungefiltertes Bild. (Große Version anzeigen)

Um diesen Effekt zu erzielen, fügen wir eine einzelne CSS-Zeile hinzu: filter: grayscale(1) . Dieser Filter entsättigt das Bild und kann mit jedem numerischen oder prozentualen Wert zwischen 0 und 1 (oder 0 % bis 100 %) verwendet werden. Hinweis: Derzeit muss Filtern für WebKit-basierte Browser das Präfix -webkit- vorangestellt werden. Eine Lösung wie Autoprefixer würde jedoch die Notwendigkeit beseitigen, sie von Hand hinzuzufügen.

Live-Demo – CSS-Filter

 .cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }

Hintergrund-Mischmodus

CSS-Mischmodi bieten eine endlose Vielfalt an Optionen für Bildeffektkombinationen. Es gibt zwei Möglichkeiten, Mischmodi zu verwenden: die mix-blend-mode Eigenschaft und die background-blend-mode Eigenschaft.

  • mix-blend-mode ist die Eigenschaft, die beschreibt, wie sich das Element mit dem Inhalt dahinter vermischt.
  • background-blend-mode wird für Elemente mit mehreren Hintergründen verwendet und beschreibt die Beziehung zwischen diesen Hintergründen.

Wir verwenden den background-blend-mode: luminosity , um in unserem Beispiel Luminanzkanäle über einen grauen Hintergrund zu ziehen, was zu einem Graustufenbild führt. Beachten Sie, dass die Hintergrundreihenfolge konstant ist: Hintergrundbilder müssen immer vor Volltonfarben oder Farbverläufen angeordnet werden, damit Effekte richtig wiedergegeben werden . Farbe muss die letzte Hintergrundebene sein. Dies ist auch ein Schutz gegen ältere Browser, die den background-blend-mode nicht unterstützen – das Bild wird immer noch ohne den Effekt gerendert.

Der einzige Unterschied zu den Mischmodi und dem CSS-Filter besteht darin, dass wir jetzt mehrere Hintergründe haben und background-blend-mode: luminosity verwenden, das die Luminanzwerte aus dem oberen Bild (dem Vogeltester) erfasst und diese Helligkeitswerte über a schichtet grauer zweiter Hintergrund.

Live-Demo – Hintergrundmischmodus

 .cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }

Im Moment ist dies die neueste und daher am wenigsten unterstützte Option, obwohl sie in Chrome und Firefox immer noch gut funktioniert und teilweise Safari-Unterstützung bietet. Hinweis: Safari unterstützt alle Mischmodi mit Ausnahme der HSL-basierten Mischmodi: Farbton, Sättigung, Farbe und Helligkeit.

HTML5-Leinwand

HTML5 <canvas> ermöglicht eine Menge Flexibilität bei der Bildbearbeitung, da wir Zugriff auf die Daten jedes einzelnen Pixels haben (insbesondere über canvasContext.getImageData ) und jeden über JavaScript bearbeiten können. Diese Methode ist jedoch die komplexeste und mit dem meisten Overhead verbunden. Aufgrund von Sicherheitsbedenken weist es auch einige Nuancen bei Cross-Origin-Problemen auf.

Um den Cross-Origin-Fehler in Chrome zu beheben, muss Ihr Bild auf einer CORS-freundlichen Website (Cross-Origin Resource Sharing) wie GitHub Pages oder Dropbox gehostet und crossOrigin="Anonymous" angegeben werden. Sehen Sie sich das Live-Beispiel für eine Demonstration an.

Um mit <canvas> einen Graustufeneffekt zu erzielen, entfernen Sie die roten, grünen und blauen Komponenten von allen äußeren Werten im Pixelwert, während die Leuchtkraft (Helligkeit) beibehalten wird. Eine Möglichkeit, dies zu tun, besteht darin, die RGB-Werte wie folgt zu mitteln: grayscale = (red + green + blue) / 3; .

Im folgenden Beispiel verwenden wir die RGBa-Werte im Format (R,G,B,a) in den Bilddaten; der rote Kanal ist data[0] , der grüne Kanal ist data[1] und so weiter. Wir erhalten dann die Helligkeitsstufe jedes dieser Kanäle (die Helligkeit) und mitteln sie, um das Bild in Graustufen umzuwandeln.

Live-Demo – HTML5-Canvas

SVG-Filter

SVG-Filter haben die breiteste Unterstützung (sogar in Internet Explorer und Edge!) und sind auch (fast) genauso einfach zu verwenden wie CSS-Filter direkt. Sie können sie mit derselben filter verwenden. Tatsächlich stammen CSS-Filter aus SVG-Filtern. Wie bei der Leinwand ermöglichen Ihnen SVG-Filter, die flache Ebene zweidimensionaler Effekte zu überschreiten, da Sie die WebGL-Schattierung nutzen können, um noch komplexere Ergebnisse zu erzielen.

Es gibt einige Möglichkeiten, einen SVG-Filter anzuwenden, aber in diesem Fall verwenden wir aus Gründen der Konsistenz weiterhin die filter Eigenschaft für das Hintergrundbild, genau wie das CSS-Filter-Beispiel. Der größte Unterschied zu SVG-Filtern besteht darin, dass wir darauf achten müssen, diesen Filter mit dem richtigen Pfad einzuschließen und zu verknüpfen. Das bedeutet, dass wir das SVG auf der Seite über dem Element importieren müssen, in dem wir es verwenden (was durch die Verwendung von Templating-Engine und Include-Anweisungen vereinfacht werden kann).

Live-Demo – SVG-Filter

 <svg> <filter> <feColorMatrix type="saturate" values="0"/> </filter> </svg>
 .svgfilter-gray { background: url('img/bird.jpg'); -webkit-filter: url(#grayscale-filter); filter: url(#grayscale-filter); }

Filterleistung

Wie stapeln sich diese also, wenn es um die anfängliche Renderleistung geht? Ich habe für jede Testseite eine Testseite erstellt und die WebPagetest-Vergleichsfunktion in Chrome 47 verwendet. Wenn man bedenkt, dass jeder Test leicht unterschiedliche Ergebnisse lieferte, kann der Gesamttrend wie folgt zusammengefasst werden:

Die Methoden CSS-Filter, SVG-Filter und CSS-Mischmodus wurden alle in relativ ähnlichen Zeitrahmen geladen. Manchmal war der SVG-Filter schneller als der CSS-Mischmodus (aber immer knapp) und umgekehrt. Der CSS-Filter wurde im Allgemeinen am schnellsten geladen, und <canvas> war immer am langsamsten. Dies ist die wichtigste Erkenntnis, die gewonnen wurde. <canvas> hinkte den anderen Methoden beim Rendern des Bildes regelmäßig hinterher.

Der Fairness halber wollte ich auch die Ladezeit für mehrere Bilder vergleichen. Ich habe jeweils zehn Wiedergaben erstellt (statt nur einer) und die Tests erneut durchgeführt:

Die Ergebnisse waren ähnlich (beachten Sie, dass es bei jedem Test leichte Abweichungen gab). Der CSS-Filter war in diesem Fall 0,1 ms langsamer, was zeigt, dass die Ergebnisse zwischen CSS-Filtern, Mischmodi und SVG-Filtern für die schnellste Methode nicht schlüssig sind. Allerdings hinkte HTML5 <canvas> im Vergleich deutlich hinterher.

Wenn Sie sich die Seitenladezeit über JavaScript-Render- und Paint-Renderzeit genauer ansehen, können Sie sehen, dass sich dieser Trend fortsetzt.

(Große Version anzeigen)
Filter Typ Zeit zum Rendern Zeit zum Malen
CSS-Filter 12,94 ms 4,28 ms
CSS-Mischmodus 12,10 ms 4,45 ms
SVG-Filter 14,77 ms 5,80 ms
Canvas-Filter 15,23 ms 10,73 ms

Auch hier brauchte <canvas> die längste Zeit zum Rendern und Malen, während die beiden CSS-Optionen am schnellsten waren, wobei SVG in der Mitte lag.

Diese Ergebnisse sind sinnvoll, da <canvas> jedes einzelne Pixel nimmt und eine Operation daran durchführt, bevor wir überhaupt ein Bild sehen können. Dies erfordert beim Rendern viel Rechenleistung. Obwohl SVGs normalerweise für Vektorgrafiken verwendet werden, würde ich sie immer noch gegenüber <canvas> empfehlen, wenn es um Rasterbildeffekte geht. SVG ist nicht nur schneller, sondern auch viel einfacher zu handhaben und flexibler innerhalb des DOM. Im Allgemeinen sind CSS-Filter noch optimierter als SVG-Filter, da sie in der Vergangenheit Verknüpfungen waren, die aus SVG-Filtern hervorgingen und daher in Browsern optimiert wurden.

#kein Filter

Wie wäre es, wenn Sie keinen Filter verwenden? Ich habe unsere insgesamt schnellste Methode (Hinzufügen eines CSS-Filters) mit der Bearbeitung Ihres Bildes in einer Fotobearbeitungssoftware vor dem Hochladen verglichen (ich habe die Vorschau unter Mac OS X verwendet, um die Sättigung zu entfernen). Bei der Vorbearbeitung des Bildes fand ich in meinen Tests eine konsistente Leistungsverbesserung von 0,1 ms:

Fazit

Bildfilter sind eine unterhaltsame und effektive Methode, um visuelle Einheit und Ästhetik im Web bereitzustellen. Denken Sie daran, dass sie mit einem leichten Leistungseinbruch einhergehen, aber auch mit den Vorteilen eines schnellen Designs im Browser und der Möglichkeit, Interaktionen mit zu gestalten.

Verwenden Sie für einfache Bildeffekte CSS-Filter, da sie die breiteste Unterstützung und einfachste Verwendung haben. Für komplexere Bildeffekte sehen Sie sich SVG-Filter oder CSS-Mischmodi an. SVG-Filtereffekte sind wegen ihrer Kanalbearbeitungsfunktionen und feColorMatrix besonders schön. CSS-Mischmodi bieten auch einige wirklich schöne visuelle Effekte mit überlappenden Elementen auf der Seite. Sie können ähnliche Mischmodi innerhalb von SVG verwenden (z. B. feBlend ), obwohl sie dem CSS background-blend-mode Mischmodus in dem Sinne ähneln, dass die Interaktion das SVG selbst betrifft und nicht mit umgebenden Elementen, wie es mix-blend-mode zulässt. Verwenden Sie einfach nicht <canvas> für Filter.