Confrontation des performances des effets d'image Web

Publié: 2022-03-10
Résumé rapide ↬ Alors que les navigateurs améliorent constamment leurs capacités de rendu graphique, la capacité de véritablement concevoir en leur sein devient de plus en plus une réalité. Quelques lignes de code peuvent désormais avoir un impact visuel rapide et spectaculaire et permettre une cohérence sans trop d'effort . Et comme pour la plupart des choses dans le développement Web, il existe souvent de nombreuses façons d'obtenir le même effet. Dans cet article, nous examinerons l'un des effets d'image les plus populaires, les niveaux de gris, et évaluerons à la fois la facilité de mise en œuvre et les implications en termes de performances du canevas HTML, des filtres SVG, CSS et des modes de fusion CSS. Lequel va gagner ?

Alors que les navigateurs améliorent constamment leurs capacités de rendu graphique, la capacité de véritablement concevoir en leur sein devient de plus en plus une réalité. Quelques lignes de code peuvent désormais avoir un impact visuel rapide et spectaculaire et permettre une cohérence sans trop d'effort . Et comme pour la plupart des choses dans le développement Web, il existe souvent de nombreuses façons d'obtenir le même effet.

Dans cet article, nous examinerons l'un des effets d'image les plus populaires, les niveaux de gris, et évaluerons à la fois la facilité de mise en œuvre et les implications en termes de performances du canevas HTML, des filtres SVG, CSS et des modes de fusion CSS. Lequel va gagner ?

Lectures complémentaires sur SmashingMag :

  • Confrontation des performances des effets d'image Web
  • HTML5 : les faits et les mythes
  • Redimensionnement d'image efficace avec ImageMagick
  • Techniques intelligentes d'optimisation JPEG

Les filtres sur le Web fonctionnent comme une lentille posée sur une image. Ils sont appliqués à l'image après que le navigateur a rendu la mise en page et la peinture initiale. Dans les navigateurs compatibles, les filtres peuvent être appliqués individuellement ou superposés. Parce qu'ils peuvent être appliqués en tant que modifications d'image après le rendu initial, et sont probablement une amélioration, les filtres se dégradent gracieusement en n'étant simplement pas visibles dans les navigateurs qui ne les prennent pas en charge.

Plus après saut! Continuez à lire ci-dessous ↓

Filtres CSS

Commençons par la méthode la plus simple pour produire un effet de niveaux de gris : l'humble mais puissant filtre CSS.

image d'oiseau non filtrée
Image non filtrée. (Voir la grande version)

Pour obtenir cet effet, nous ajoutons une seule ligne de CSS : filter: grayscale(1) . Ce filtre désature l'image et peut être utilisé avec n'importe quelle valeur numérique ou en pourcentage entre 0 et 1 (ou 0 % à 100 %). Remarque : actuellement, les filtres pour les navigateurs basés sur WebKit doivent être préfixés par -webkit- . Cependant, une solution telle que Autoprefixer éliminerait le besoin de les ajouter à la main.

Démo en direct – Filtre CSS

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

Mode de fusion d'arrière-plan

Les modes de fusion CSS offrent une variété infinie d'options pour les combinaisons d'effets d'image. Il existe deux manières d'utiliser les modes de fusion : la propriété mix-blend-mode et la propriété background-blend-mode .

  • mix-blend-mode est la propriété qui décrit comment l'élément se fondra avec le contenu qu'il contient.
  • background-blend-mode est utilisé pour les éléments avec plusieurs arrière-plans et décrit la relation entre ces arrière-plans.

Nous utiliserons le background-blend-mode: luminosity pour tirer les canaux de luminosité sur un fond gris dans notre exemple, résultant en une image en niveaux de gris. Une chose à noter est que l'ordre d'arrière-plan est constant : les images d'arrière-plan doivent toujours être classées avant les couleurs unies ou les arrière-plans dégradés pour que les effets s'affichent correctement . La couleur doit être le dernier calque d'arrière-plan. C'est également une protection contre les anciens navigateurs qui ne prennent pas en charge background-blend-mode - l'image sera toujours rendue sans effet.

La seule différence avec les modes de fusion et le filtre CSS est que nous avons maintenant plusieurs arrière-plans et que nous utilisons background-blend-mode: luminosity , qui récupère les valeurs de luminosité de l'image supérieure (le testeur d'oiseaux) et superpose ces valeurs de luminosité sur un deuxième fond gris.

Démo en direct - Mode de fusion d'arrière-plan

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

Pour le moment, il s'agit de l'option la plus récente et donc la moins prise en charge, bien qu'elle fonctionne toujours bien dans Chrome et Firefox, et qu'elle soit partiellement prise en charge par Safari. Remarque : Safari prend en charge tous les modes de fusion, à l'exception des modes de fusion basés sur HSL : teinte, saturation, couleur et luminosité.

Canevas HTML5

HTML5 <canvas> permet une tonne de flexibilité en matière de manipulation d'images, car nous avons accès aux données de chaque pixel individuel (en particulier via canvasContext.getImageData ) et pouvons les manipuler via JavaScript. Cette méthode, cependant, est la plus complexe et entraîne le plus de frais généraux. Il a également quelques nuances dans les problèmes d'origine croisée en raison de problèmes de sécurité.

Pour corriger l'erreur d'origine croisée dans Chrome, votre image devra être hébergée sur un site convivial de partage de ressources d'origine croisée (CORS) comme GitHub Pages ou Dropbox, et spécifier crossOrigin="Anonymous" . Voir l'exemple en direct pour une démonstration.

La façon d'obtenir un effet de niveaux de gris avec <canvas> est de supprimer les composants rouge, vert et bleu de toute valeur périphérique dans la valeur de pixel tout en maintenant son niveau de luminosité (luminosité). Une façon de faire est de faire la moyenne des valeurs RVB comme ceci : grayscale = (red + green + blue) / 3; .

Dans l'exemple ci-dessous, nous utilisons les valeurs RGBa au format (R,G,B,a) dans les données d'image ; le canal rouge est data[0] , le canal vert est data[1] , etc. Nous obtenons ensuite le niveau de luminosité de chacun de ces canaux (la luminosité) et en faisons la moyenne pour transformer l'image en niveaux de gris.

Démo en direct – Toile HTML5

Filtre SVG

Les filtres SVG ont le support le plus large (même dans Internet Explorer et Edge !) et sont aussi (presque) aussi faciles à utiliser que les filtres CSS directement. Vous pouvez les utiliser avec la même propriété de filter . En fait, les filtres CSS sont issus des filtres SVG. Comme avec le canevas, les filtres SVG vous permettent de transcender le plan plat des effets bidimensionnels, car vous pouvez tirer parti de l'ombrage WebGL pour créer des résultats encore plus complexes.

Il existe plusieurs façons d'appliquer un filtre SVG, mais dans ce cas, nous utiliserons toujours la propriété filter sur l'image d'arrière-plan, tout comme l'exemple de filtre CSS pour la cohérence. La plus grande différence avec les filtres SVG est que nous devons faire attention à inclure et à lier ce filtre avec le bon chemin. Cela signifie que nous devons importer le SVG sur la page au-dessus de l'élément dans lequel nous l'utilisons (ce qui peut être facilité en utilisant le moteur de modèles et les instructions d'inclusion).

Démo en direct – Filtre 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); }

Performances du filtre

Alors, comment cela se compare-t-il en ce qui concerne les performances de rendu initiales ? J'ai créé une page de test pour chacun et utilisé la fonction de comparaison WebPagetest dans Chrome 47. En gardant à l'esprit que chaque test a donné des résultats légèrement différents, la tendance générale peut être résumée comme suit :

Les méthodes de filtre CSS, de filtre SVG et de mode de fusion CSS sont toutes chargées dans des délais relativement similaires. Parfois, le filtre SVG était plus rapide que le mode de fusion CSS (mais toujours à peine) et vice versa. Le filtre CSS était généralement parmi les plus rapides à charger et <canvas> était toujours le plus lent. C'est l'information la plus significative recueillie. <canvas> était régulièrement en retard sur les autres méthodes de rendu de l'image.

Par souci d'équité, je voulais également comparer le temps de chargement de plusieurs images. J'ai créé dix rendus de chacun (au lieu d'un seul) et j'ai refait les tests :

Les résultats étaient similaires (gardez à l'esprit qu'il y avait de légères variations dans chaque test). Le filtre CSS était 0,1 ms plus lent dans ce cas, ce qui montre qu'entre les filtres CSS, les modes de fusion et les filtres SVG, les résultats ne sont pas concluants pour la méthode la plus rapide. Cependant, HTML5 <canvas> était sensiblement à la traîne en comparaison.

En examinant plus en profondeur le temps de chargement de la page via le rendu JavaScript et le temps de rendu de la peinture, vous pouvez voir cette tendance se poursuivre.

(Voir la grande version)
Type de filtre Temps de rendu Il est temps de peindre
Filtre CSS 12,94 ms 4,28 ms
Mode de fusion CSS 12.10ms 4,45 ms
Filtre SVG 14,77 ms 5.80ms
Filtre de toile 15,23 ms 10,73 ms

Encore une fois, <canvas> a pris le plus de temps à rendre et le plus de temps à peindre, tandis que les deux options CSS étaient les plus rapides, SVG venant au milieu.

Ces résultats ont du sens, car <canvas> prend chaque pixel individuel et effectue une opération dessus avant que nous ne puissions jamais voir la moindre image. Cela prend beaucoup de puissance de traitement au moment du rendu. Alors que normalement les SVG sont utilisés pour les graphiques vectoriels, je les recommanderais toujours fortement sur <canvas> lorsqu'il s'agit d'effets d'image raster. Non seulement SVG est plus rapide, mais il est également beaucoup plus facile à gérer et plus flexible dans le DOM. Généralement, les filtres CSS sont encore plus optimisés que les filtres SVG, car historiquement ce sont des raccourcis émergeant des filtres SVG et donc optimisés dans les navigateurs.

#pas de filtre

Et si vous n'utilisiez aucun filtre ? J'ai comparé notre méthode la plus rapide (ajout d'un filtre CSS) à l'édition de votre image dans un logiciel de retouche photo avant de la télécharger (j'ai utilisé Aperçu sur Mac OS X pour supprimer la saturation). Lors de la pré-édition de l'image, j'ai constaté une amélioration constante des performances de 0,1 ms dans mes tests :

Conclusion

Les filtres d'image sont un moyen amusant et efficace de fournir une unité visuelle et un attrait esthétique sur le Web. Gardez à l'esprit qu'ils ont un léger impact sur les performances, mais aussi avec les avantages d'une conception rapide dans le navigateur et la possibilité de concevoir des interactions avec.

Pour des effets d'image simples, utilisez des filtres CSS, car ils ont le support le plus large et l'utilisation la plus simple. Pour des effets d'image plus complexes, consultez les filtres SVG ou les modes de fusion CSS. Les effets de filtre SVG sont particulièrement agréables en raison de leurs capacités de manipulation de canaux et de feColorMatrix . Les modes de fusion CSS offrent également de très beaux effets visuels avec des éléments qui se chevauchent sur la page. Vous pouvez utiliser des modes de fusion similaires dans SVG (tels que feBlend ), bien qu'ils s'apparentent à CSS background-blend-mode dans le sens où l'interaction se rapporte au SVG lui-même et non aux éléments environnants, comme le permet mix-blend-mode . N'utilisez simplement pas <canvas> pour les filtres.