Pokaz wydajności efektów graficznych w sieci Web
Opublikowany: 2022-03-10Ponieważ przeglądarki stale poprawiają swoje możliwości renderowania graficznego, możliwość prawdziwego projektowania w nich staje się coraz bardziej rzeczywistością. Kilka linijek kodu może teraz mieć szybki i dramatyczny efekt wizualny oraz zapewnić spójność bez większego wysiłku . I jak w przypadku większości rzeczy związanych z tworzeniem stron internetowych, często istnieje wiele sposobów na osiągnięcie tego samego efektu.
W tym poście przyjrzymy się jednemu z najpopularniejszych efektów graficznych, skali szarości, i ocenimy zarówno łatwość implementacji, jak i wpływ na wydajność kanwy HTML, SVG, filtrów CSS i trybów mieszania CSS. Który wygra?
Dalsze czytanie na SmashingMag:
- Pokaz wydajności efektów graficznych w sieci Web
- HTML5: fakty i mity
- Wydajna zmiana rozmiaru obrazu dzięki ImageMagick
- Sprytne techniki optymalizacji JPEG
Filtry w sieci działają jak soczewka nałożona na obraz. Są one stosowane do obrazu po wyrenderowaniu przez przeglądarkę układu i początkowego malowania. W obsługiwanych przeglądarkach filtry można nakładać pojedynczo lub nakładać na siebie. Ponieważ można je zastosować jako modyfikacje obrazu po wstępnym renderowaniu i prawdopodobnie są one ulepszeniem, filtry zgrabnie degradują się, po prostu niewidoczne w przeglądarkach, które ich nie obsługują.
Filtry CSS
Zacznijmy od najprostszej metody uzyskania efektu skali szarości: skromnego, ale potężnego filtra CSS.

Aby osiągnąć ten efekt, dodajemy pojedynczą linię CSS: filter: grayscale(1)
. Ten filtr zmniejsza nasycenie obrazu i może być używany z dowolną wartością liczbową lub procentową z zakresu od 0 do 1 (lub od 0% do 100%). Uwaga: obecnie filtry dla przeglądarek opartych na WebKit muszą być poprzedzone prefiksem -webkit-
. Jednak rozwiązanie takie jak Autoprefixer wyeliminowałoby potrzebę ich ręcznego dodawania.
Demo na żywo – Filtr CSS
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
Tryb mieszania tła
Tryby mieszania CSS zapewniają nieskończoną różnorodność opcji kombinacji efektów graficznych. Istnieją dwa sposoby używania trybów mieszania: właściwość mix-blend-mode
i właściwość background-blend-mode
.
-
mix-blend-mode
to właściwość, która opisuje, w jaki sposób element będzie łączył się z treścią za nim. -
background-blend-mode
jest używany dla elementów z wieloma tłami i opisuje relacje między tymi tłami.
W naszym przykładzie użyjemy background-blend-mode: luminosity
, aby przeciągnąć kanały jasności na szarym tle, co da obraz w skali szarości. Należy zauważyć, że kolejność tła jest stała: obrazy tła muszą zawsze być uporządkowane przed jednolitymi kolorami lub tłem gradientowym, aby efekty były poprawnie renderowane . Kolor musi być ostatnią warstwą tła. Jest to również zabezpieczenie przed starszymi przeglądarkami, które nie obsługują background-blend-mode
– obraz nadal będzie renderowany bez efektu.
Jedyna różnica między trybami mieszania i filtrem CSS polega na tym, że mamy teraz wiele teł i używamy background-blend-mode: luminosity
, który pobiera wartości jasności z górnego obrazu (tester ptaków) i nakłada je na szare drugie tło.
Demo na żywo – tryb mieszania tła
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
W tej chwili jest to najnowsza, a przez to najmniej obsługiwana opcja, chociaż nadal działa dobrze w Chrome i Firefox oraz ma częściową obsługę Safari. Uwaga: Safari obsługuje wszystkie tryby mieszania z wyjątkiem trybów mieszania opartych na HSL: odcień, nasycenie, kolor i jasność.
Płótno HTML5
HTML5 <canvas>
pozwala na dużą elastyczność, jeśli chodzi o manipulowanie obrazami, ponieważ mamy dostęp do danych każdego pojedynczego piksela (w szczególności poprzez canvasContext.getImageData
) i możemy manipulować każdym z nich za pomocą JavaScript. Ta metoda jest jednak najbardziej złożona i wiąże się z największymi kosztami. Ma również kilka niuansów w kwestiach cross-origin ze względu na obawy dotyczące bezpieczeństwa.
Aby naprawić błąd cross-origin w Chrome, Twój obraz musi być hostowany w przyjaznej witrynie do udostępniania zasobów między różnymi źródłami (CORS), takiej jak GitHub Pages lub Dropbox, i określić crossOrigin="Anonymous"
. Zobacz przykład na żywo, aby zobaczyć demonstrację.
Sposobem na osiągnięcie efektu skali szarości za pomocą <canvas>
jest usunięcie składowych czerwonego, zielonego i niebieskiego z dowolnej wartości odstającej w wartości piksela przy jednoczesnym zachowaniu jego poziomu jasności (jasności). Jednym ze sposobów na to jest uśrednienie wartości RGB w następujący sposób: grayscale = (red + green + blue) / 3;
.

W poniższym przykładzie używamy wartości RGBa w formacie (R,G,B,a)
w danych obrazu; czerwony kanał to data[0]
, zielony kanał to data[1]
i tak dalej. Następnie uzyskujemy poziom jasności każdego z tych kanałów (jasność) i uśredniamy je, aby zmienić skalę szarości obrazu.
Demo na żywo – HTML5 Canvas
Filtr SVG
Filtry SVG mają najszersze wsparcie (nawet w Internet Explorerze i Edge!), a także są (prawie) tak łatwe w użyciu, jak bezpośrednio filtry CSS. Możesz ich używać z tą samą właściwością filter
. W rzeczywistości filtry CSS wywodziły się z filtrów SVG. Podobnie jak w przypadku kanwy, filtry SVG pozwalają przekroczyć płaską płaszczyznę efektów dwuwymiarowych, ponieważ można wykorzystać cieniowanie WebGL do tworzenia jeszcze bardziej złożonych wyników.
Istnieje kilka sposobów na zastosowanie filtra SVG, ale w tym przypadku nadal będziemy używać właściwości filter
na obrazie tła, tak jak przykład filtra CSS w celu zapewnienia spójności. Największą różnicą w przypadku filtrów SVG jest to, że musimy uważać, aby uwzględnić ten filtr i połączyć go z odpowiednią ścieżką. Oznacza to, że musimy zaimportować SVG na stronie nad elementem, w którym go używamy (co można ułatwić, korzystając z silnika szablonów i instrukcji include).
Demo na żywo – filtr SVG
<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); }
Wydajność filtra
Więc jak się układają, jeśli chodzi o początkową wydajność renderowania? Zrobiłem stronę testową dla każdego i użyłem funkcji porównania WebPagetest w Chrome 47. Mając na uwadze, że każdy test dawał nieco inne wyniki, ogólny trend można podsumować w następujący sposób:
Wszystkie metody filtru CSS, filtru SVG i trybu mieszania CSS ładowały się w stosunkowo podobnych ramach czasowych. Czasami filtr SVG był szybszy niż tryb mieszania CSS (ale zawsze ledwo) i na odwrót. Filtr CSS był na ogół jednym z najszybszych do załadowania, a <canvas>
zawsze był najwolniejszy. To jest najważniejsze, jakie udało się uzyskać. <canvas>
regularnie pozostawał w tyle za innymi metodami renderowania obrazu.
Aby zachować uczciwość, chciałem również porównać czas ładowania wielu obrazów. Stworzyłem dziesięć wersji każdego z nich (zamiast tylko jednego) i ponownie przeprowadziłem testy:
Wyniki były podobne (należy pamiętać, że w każdym teście występowały niewielkie różnice). Filtr CSS był w tym przypadku o 0,1 ms wolniejszy, co pokazuje, że pomiędzy filtrami CSS, trybami mieszania i filtrami SVG wyniki są niejednoznaczne dla najszybszej metody. Jednak <canvas>
HTML5 pozostało w porównaniu z zauważalnym opóźnieniem.
Przyglądając się bliżej czasowi wczytywania strony za pomocą renderowania JavaScript i czasu renderowania malowania, można zauważyć, że ten trend się utrzymuje.

Typ filtra | Czas renderowania | Czas na malowanie |
---|---|---|
Filtr CSS | 12,94 ms | 4,28 ms |
Tryb mieszania CSS | 12.10ms | 4,45 ms |
Filtr SVG | 14,77 ms | 5.80ms |
Filtr płócienny | 15,23 ms | 10,73 ms |
Ponownie, najdłużej renderowanie i malowanie zajęło <canvas>
, podczas gdy dwie opcje CSS były najszybsze, SVG w środku.
Te wyniki mają sens, ponieważ <canvas>
pobiera każdy piksel i wykonuje na nim operację, zanim w ogóle będziemy mogli zobaczyć jakikolwiek obraz. Wymaga to dużej mocy obliczeniowej w czasie renderowania. Podczas gdy normalnie SVG są używane do grafiki wektorowej, nadal gorąco polecam je zamiast <canvas>
, gdy mamy do czynienia z efektami obrazu rastrowego. SVG jest nie tylko szybszy, ale także łatwiejszy w obsłudze i bardziej elastyczny w DOM. Ogólnie filtry CSS są jeszcze bardziej zoptymalizowane niż filtry SVG, ponieważ historycznie są to skróty wyłaniające się z filtrów SVG, a tym samym zoptymalizowane w przeglądarkach.
#bez filtra
A co z brakiem filtra? Porównałem naszą najszybszą metodę (dodanie filtra CSS) z edycją obrazu w oprogramowaniu do edycji zdjęć przed jego przesłaniem (użyłem podglądu w systemie Mac OS X, aby usunąć nasycenie). Podczas wstępnej edycji obrazu zauważyłem w moich testach stałą poprawę wydajności o 0,1 ms:
Wniosek
Filtry obrazu to zabawny i skuteczny sposób na zapewnienie wizualnej jedności i estetycznego wyglądu w sieci. Pamiętaj, że mają one niewielki spadek wydajności, ale także korzyści płynące z szybkiego projektowania w przeglądarce i możliwości projektowania interakcji.
Do prostych efektów graficznych używaj filtrów CSS, ponieważ mają one najszersze wsparcie i najprostsze użycie. Aby uzyskać bardziej złożone efekty graficzne, zapoznaj się z filtrami SVG lub trybami mieszania CSS. Efekty filtrów SVG są szczególnie przyjemne ze względu na ich możliwości manipulacji kanałami i feColorMatrix
. Tryby mieszania CSS oferują również naprawdę fajne efekty wizualne z nakładającymi się elementami na stronie. Możesz używać podobnych trybów mieszania w SVG (takich jak feBlend
), chociaż są one podobne do background-blend-mode
CSS w tym sensie, że interakcja dotyczy samego SVG, a nie elementów otaczających, jak pozwala na to mix-blend-mode
. Tylko nie używaj <canvas>
do filtrów.