Resa dei conti delle prestazioni degli effetti delle immagini Web
Pubblicato: 2022-03-10Poiché i browser migliorano costantemente le loro capacità di rendering grafico, la capacità di progettare veramente al loro interno sta diventando sempre più una realtà. Alcune righe di codice ora possono avere un impatto visivo rapido e drammatico e consentire la coerenza senza troppi sforzi . E come con la maggior parte delle cose nello sviluppo web, ci sono spesso molti modi per ottenere lo stesso effetto.
In questo post, daremo un'occhiata a uno degli effetti immagine più popolari, la scala di grigi, e valuteremo sia la facilità di implementazione che le implicazioni sulle prestazioni della tela HTML, dei filtri SVG, CSS e delle modalità di fusione CSS. Quale vincerà?
Ulteriori letture su SmashingMag:
- Resa dei conti delle prestazioni degli effetti delle immagini Web
- HTML5: I fatti ei miti
- Ridimensionamento efficiente delle immagini con ImageMagick
- Tecniche intelligenti di ottimizzazione JPEG
I filtri sul Web funzionano come una lente posta su un'immagine. Vengono applicati all'immagine dopo che il browser ha eseguito il rendering del layout e della pittura iniziale. Nei browser di supporto, i filtri possono essere applicati singolarmente o sovrapposti. Poiché possono essere applicati come modifiche dell'immagine dopo il rendering iniziale e sono probabilmente un miglioramento, i filtri si degradano con grazia semplicemente non sono visibili nei browser che non li supportano.
Filtri CSS
Iniziamo con il metodo più semplice per produrre un effetto in scala di grigi: l'umile ma potente filtro CSS.

Per ottenere questo effetto, aggiungiamo una singola riga di CSS: filter: grayscale(1)
. Questo filtro desatura l'immagine e può essere utilizzato con qualsiasi valore numerico o percentuale compreso tra 0 e 1 (o da 0% a 100%). Nota: attualmente, i filtri per i browser basati su WebKit devono essere preceduti da -webkit-
. Tuttavia, una soluzione come Autoprefixer eliminerebbe la necessità di aggiungerli manualmente.
Demo dal vivo – Filtro CSS
.cssfilter-gray { -webkit-filter: grayscale(1); background: url('img/bird.jpg'); filter: grayscale(1); }
Modalità di fusione dello sfondo
I metodi di fusione CSS offrono una varietà infinita di opzioni per le combinazioni di effetti immagine. Esistono due modi per utilizzare le modalità di fusione: la proprietà mix-blend-mode
e la proprietà modalità background-blend-mode
.
-
mix-blend-mode
è la proprietà che descrive come l'elemento si fonderà con il contenuto dietro di esso. -
background-blend-mode
viene utilizzato per elementi con più sfondi e descrive la relazione tra questi sfondi.
Utilizzeremo la background-blend-mode: luminosity
per trascinare i canali di luminosità su uno sfondo grigio nel nostro esempio, risultando in un'immagine in scala di grigi. Una cosa da notare è che l'ordine dello sfondo è costante: le immagini di sfondo devono sempre essere ordinate prima dei colori solidi o degli sfondi sfumati affinché gli effetti vengano visualizzati correttamente . Il colore deve essere l'ultimo livello di sfondo. Questa è anche una protezione contro i browser più vecchi che non supportano background-blend-mode
: l'immagine verrà comunque renderizzata senza l'effetto.
L'unica differenza con le modalità di fusione e il filtro CSS è che ora abbiamo più sfondi e stiamo utilizzando background-blend-mode: luminosity
, che acquisisce i valori di luminosità dall'immagine in alto (il bird tester) e sovrappone quei valori di luminosità su un secondo sfondo grigio.
Demo dal vivo – Modalità di fusione dello sfondo
.cssfilter-gray { background: url('img/bird.jpg'), gray; background-blend-mode: luminosity; }
Al momento, questa è l'opzione più recente e quindi meno supportata, sebbene funzioni ancora bene in Chrome e Firefox e abbia un supporto parziale per Safari. Nota: Safari supporta tutte le modalità di fusione ad eccezione delle modalità di fusione basate su HSL: tonalità, saturazione, colore e luminosità.
Tela HTML5
HTML5 <canvas>
offre molta flessibilità quando si tratta di manipolazione delle immagini, perché abbiamo accesso ai dati di ogni singolo pixel (in particolare tramite canvasContext.getImageData
) e possiamo manipolarli tramite JavaScript. Questo metodo, tuttavia, è il più complesso e comporta il maggior sovraccarico. Presenta anche alcune sfumature nei problemi di origine incrociata a causa di problemi di sicurezza.
Per correggere l'errore di cross-origin in Chrome, la tua immagine dovrà essere ospitata su un sito compatibile con la condivisione di risorse cross-origin (CORS) come GitHub Pages o Dropbox e specificare crossOrigin="Anonymous"
. Guarda l'esempio dal vivo per una dimostrazione.
Il modo per ottenere un effetto in scala di grigi con <canvas>
consiste nell'eliminare i componenti rosso, verde e blu da qualsiasi valore esterno nel valore dei pixel mantenendone il livello di luminosità (luminosità). Un modo per farlo è calcolare la media dei valori RGB in questo modo: scala di grayscale = (red + green + blue) / 3;
.

Nell'esempio seguente, utilizziamo i valori RGBa nel formato (R,G,B,a)
nei dati dell'immagine; il canale rosso è data[0]
, il canale verde è data[1]
e così via. Quindi otteniamo il livello di luminosità di ciascuno di questi canali (la luminosità) e ne facciamo una media per trasformare la scala di grigi dell'immagine.
Demo dal vivo – Tela HTML5
Filtro SVG
I filtri SVG hanno il supporto più ampio (anche in Internet Explorer ed Edge!) e sono anche (quasi) facili da usare come i filtri CSS direttamente. Puoi usarli con la stessa proprietà del filter
. In effetti, i filtri CSS derivavano dai filtri SVG. Come con la tela, i filtri SVG ti consentono di trascendere il piano piatto degli effetti bidimensionali, poiché puoi sfruttare l'ombreggiatura WebGL per creare risultati ancora più complessi.
Esistono alcuni modi per applicare un filtro SVG, ma in questo caso utilizzeremo comunque la proprietà filter
sull'immagine di sfondo, proprio come l'esempio del filtro CSS per coerenza. La più grande differenza con i filtri SVG è che dobbiamo fare attenzione a includere e collegare a questo filtro con il percorso corretto. Ciò significa che dobbiamo importare l'SVG nella pagina sopra l'elemento in cui lo stiamo usando (cosa che può essere resa più semplice usando il motore di template e le istruzioni include).
Demo dal vivo – Filtro 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); }
Prestazioni del filtro
Quindi, come si accumulano questi quando si tratta di prestazioni di rendering iniziali? Ho creato una pagina di test per ciascuno e ho utilizzato la funzione di confronto WebPagetest in Chrome 47. Tenendo presente che ogni test ha fornito risultati leggermente diversi, la tendenza generale può essere riassunta come segue:
I metodi filtro CSS, filtro SVG e modalità di fusione CSS sono stati tutti caricati in intervalli di tempo relativamente simili. A volte il filtro SVG era più veloce della modalità di fusione CSS (ma sempre a malapena) e viceversa. Il filtro CSS era generalmente tra i più veloci da caricare e <canvas>
era sempre il più lento. Questa è l'intuizione più significativa raccolta. <canvas>
era regolarmente in ritardo rispetto agli altri metodi nel rendering dell'immagine.
Per correttezza, volevo anche confrontare il tempo di caricamento per più immagini. Ho creato dieci versioni di ciascuna (invece di una sola) e ho eseguito di nuovo i test:
I risultati sono stati simili (tieni presente che c'erano lievi variazioni in ogni test). Il filtro CSS in questo caso era 0,1 ms più lento, dimostrando che tra filtri CSS, modalità di fusione e filtri SVG, i risultati sono inconcludenti per il metodo più veloce. Tuttavia, HTML5 <canvas>
è rimasto notevolmente indietro rispetto al confronto.
Dando un'occhiata più in profondità al tempo di caricamento della pagina tramite il rendering JavaScript e il tempo di rendering della vernice, puoi vedere che questa tendenza continua.

Tipo di filtro | Tempo per rendere | Tempo per dipingere |
---|---|---|
Filtro CSS | 12,94 ms | 4,28 ms |
Modalità di fusione CSS | 12.10 ms | 4,45 ms |
Filtro SVG | 14,77 ms | 5,80 ms |
Filtro tela | 15,23 ms | 10,73 ms |
Ancora una volta, <canvas>
ha impiegato il tempo più lungo per il rendering e il tempo più lungo per dipingere, mentre le due opzioni CSS erano le più veloci, SVG nel mezzo.
Questi risultati hanno senso, perché <canvas>
sta prendendo ogni singolo pixel ed esegue un'operazione su di esso prima che siamo in grado di vedere qualsiasi immagine. Ciò richiede molta potenza di elaborazione al momento del rendering. Mentre normalmente gli SVG vengono utilizzati per la grafica vettoriale, li consiglio vivamente su <canvas>
quando si tratta di effetti di immagine raster. Non solo SVG è più veloce, ma è anche molto più facile da gestire e più flessibile all'interno del DOM. In genere, i filtri CSS sono ancora più ottimizzati dei filtri SVG, poiché storicamente sono scorciatoie che emergono dai filtri SVG e, quindi, ottimizzati nei browser.
#senza Filtro
Che ne dici di non usare filtri? Ho confrontato il nostro metodo più veloce in generale (aggiungere un filtro CSS) alla modifica dell'immagine nel software di fotoritocco prima di caricarla (ho usato Anteprima su Mac OS X per rimuovere la saturazione). Durante la pre-editing dell'immagine, ho riscontrato un consistente miglioramento delle prestazioni di 0,1 ms nei miei test:
Conclusione
I filtri immagine sono un modo divertente ed efficace per fornire unità visiva e appeal estetico sul web. Tieni presente che hanno un leggero calo delle prestazioni, ma anche i vantaggi di una progettazione rapida nel browser e l'opportunità di progettare interazioni con.
Per semplici effetti immagine usa i filtri CSS, poiché hanno il supporto più ampio e l'utilizzo più semplice. Per effetti immagine più complessi, controlla i filtri SVG o le modalità di fusione CSS. Gli effetti del filtro SVG sono particolarmente belli grazie alle loro capacità di manipolazione dei canali e feColorMatrix
. Le modalità di fusione CSS offrono anche alcuni effetti visivi davvero belli con elementi sovrapposti sulla pagina. Puoi utilizzare modalità di fusione simili all'interno di SVG (come feBlend
), sebbene siano simili alla background-blend-mode
CSS nel senso che l'interazione riguarda l'SVG stesso e non con gli elementi circostanti, come consente mix-blend-mode
. Basta non usare <canvas>
per i filtri.