Enfrentamiento de rendimiento de efectos de imagen web

Publicado: 2022-03-10
Resumen rápido ↬ A medida que los navegadores mejoran constantemente sus capacidades de representación gráfica, la capacidad de diseñar verdaderamente dentro de ellos se está convirtiendo en una realidad. Unas pocas líneas de código ahora pueden tener un impacto visual rápido y espectacular, y permitir la coherencia sin mucho esfuerzo . Y como con la mayoría de las cosas en el desarrollo web, a menudo hay muchas formas de lograr el mismo efecto. En esta publicación, veremos uno de los efectos de imagen más populares, la escala de grises, y evaluaremos tanto la facilidad de implementación como las implicaciones de rendimiento del lienzo HTML, SVG, filtros CSS y modos de combinación CSS. ¿Cuál ganará?

A medida que los navegadores mejoran constantemente sus capacidades de representación gráfica, la capacidad de diseñar verdaderamente dentro de ellos se está convirtiendo en una realidad. Unas pocas líneas de código ahora pueden tener un impacto visual rápido y espectacular, y permitir la coherencia sin mucho esfuerzo . Y como con la mayoría de las cosas en el desarrollo web, a menudo hay muchas formas de lograr el mismo efecto.

En esta publicación, veremos uno de los efectos de imagen más populares, la escala de grises, y evaluaremos tanto la facilidad de implementación como las implicaciones de rendimiento del lienzo HTML, SVG, filtros CSS y modos de combinación CSS. ¿Cuál ganará?

Lectura adicional en SmashingMag:

  • Enfrentamiento de rendimiento de efectos de imagen web
  • HTML5: los hechos y los mitos
  • Cambio de tamaño de imagen eficiente con ImageMagick
  • Técnicas inteligentes de optimización de JPEG

Los filtros en la web funcionan como una lente colocada sobre una imagen. Se aplican a la imagen después de que el navegador representa el diseño y la pintura inicial. En los navegadores compatibles, los filtros se pueden aplicar individualmente o en capas uno encima del otro. Debido a que se pueden aplicar como modificaciones de imagen después del renderizado inicial, y es probable que sean una mejora, los filtros se degradan con gracia al simplemente no ser visibles en los navegadores que no los admiten.

¡Más después del salto! Continúe leyendo a continuación ↓

Filtros CSS

Comencemos con el método más directo para producir un efecto de escala de grises: el humilde pero poderoso filtro CSS.

imagen de pájaro sin filtrar
Imagen sin filtrar. (Ver versión grande)

Para lograr este efecto, agregamos una sola línea de CSS: filter: grayscale(1) . Este filtro desatura la imagen y puede usarse con cualquier valor numérico o porcentual entre 0 y 1 (o 0% a 100%). Nota: actualmente, los filtros para navegadores basados ​​en WebKit deben tener el prefijo -webkit- . Sin embargo, una solución como Autoprefixer eliminaría la necesidad de agregarlos a mano.

Demostración en vivo - Filtro CSS

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

Modo de fusión de fondo

Los modos de fusión CSS brindan una variedad infinita de opciones para combinaciones de efectos de imagen. Hay dos formas de usar los modos de fusión: la propiedad mix-blend-mode y la propiedad background-blend-mode .

  • mix-blend-mode es la propiedad que describe cómo se combinará el elemento con el contenido detrás de él.
  • background-blend-mode se usa para elementos con múltiples fondos y describe la relación entre estos fondos.

Usaremos background-blend-mode: luminosity para atraer canales de luminosidad sobre un fondo gris en nuestro ejemplo, lo que resultará en una imagen en escala de grises. Una cosa a tener en cuenta es que el orden del fondo es constante: las imágenes de fondo siempre se deben ordenar antes que los colores sólidos o los fondos degradados para que los efectos se reproduzcan correctamente . El color debe ser la última capa de fondo. Esto también es una protección contra los navegadores más antiguos que no admiten background-blend-mode : la imagen seguirá mostrándose sin el efecto.

La única diferencia con los modos de fusión y el filtro CSS es que ahora tenemos varios fondos y estamos usando background-blend-mode: luminosity , que toma los valores de luminosidad de la imagen superior (el probador de aves) y superpone esos valores de brillo sobre un segundo fondo gris.

Demostración en vivo: modo de fusión de fondo

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

Por el momento, esta es la opción más nueva y, por lo tanto, menos compatible, aunque todavía funciona bien en Chrome y Firefox, y tiene soporte parcial para Safari. Nota: Safari admite todos los modos de fusión excepto los modos de fusión basados ​​en HSL: tono, saturación, color y luminosidad.

Lienzo HTML5

HTML5 <canvas> permite mucha flexibilidad en lo que respecta a la manipulación de imágenes, porque tenemos acceso a los datos de cada píxel individual (específicamente a través canvasContext.getImageData ) y podemos manipular cada uno a través de JavaScript. Este método, sin embargo, es el más complejo y conlleva la mayor parte de los gastos generales. También tiene algunos matices en los problemas de origen cruzado debido a problemas de seguridad.

Para corregir el error de origen cruzado en Chrome, su imagen deberá estar alojada en un sitio amigable para compartir recursos de origen cruzado (CORS) como GitHub Pages o Dropbox, y especificar crossOrigin="Anonymous" . Vea el ejemplo en vivo para una demostración.

La forma de lograr un efecto de escala de grises con <canvas> es eliminar los componentes rojo, verde y azul de cualquier valor externo en el valor del píxel mientras se mantiene su nivel de luminosidad (brillo). Una forma de hacerlo es promediar los valores RGB de la siguiente manera: grayscale = (red + green + blue) / 3; .

En el siguiente ejemplo, estamos usando los valores RGBa en el formato (R,G,B,a) en los datos de la imagen; el canal rojo es data[0] , el canal verde es data[1] , y así sucesivamente. Luego obtenemos el nivel de luminosidad de cada uno de estos canales (el brillo) y los promediamos para convertir la imagen en escala de grises.

Demostración en vivo: HTML5 Canvas

Filtro SVG

Los filtros SVG tienen el soporte más amplio (¡incluso en Internet Explorer y Edge!) y también son (casi) tan fáciles de usar como los filtros CSS directamente. Puede usarlos con la misma propiedad de filter . De hecho, los filtros CSS surgieron de los filtros SVG. Al igual que con el lienzo, los filtros SVG le permiten trascender el plano plano de los efectos bidimensionales, ya que puede aprovechar el sombreado WebGL para crear resultados aún más complejos.

Hay algunas formas de aplicar un filtro SVG, pero en este caso seguiremos usando la propiedad de filter en la imagen de fondo, al igual que el ejemplo del filtro CSS para mantener la coherencia. La mayor diferencia con los filtros SVG es que debemos tener cuidado de incluir y vincular este filtro con la ruta adecuada. Esto significa que necesitamos importar el SVG en la página sobre el elemento en el que lo estamos usando (lo que se puede hacer más fácil usando un motor de plantillas e incluir declaraciones).

Demostración en 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); }

Rendimiento del filtro

Entonces, ¿cómo se comparan estos cuando se trata del rendimiento de renderizado inicial? Hice una página de prueba para cada uno y usé la función de comparación WebPagetest en Chrome 47. Teniendo en cuenta que cada prueba dio resultados ligeramente diferentes, la tendencia general se puede resumir de la siguiente manera:

Los métodos de filtro CSS, filtro SVG y modo de mezcla CSS se cargaron en marcos de tiempo relativamente similares. A veces, el filtro SVG era más rápido que el modo de mezcla CSS (pero siempre apenas) y viceversa. El filtro CSS fue generalmente uno de los más rápidos para cargar, y <canvas> siempre fue el más lento. Esta es la idea más significativa obtenida. <canvas> se retrasaba regularmente con respecto a los otros métodos para representar la imagen.

Para ser justos, también quería comparar el tiempo de carga de varias imágenes. Creé diez versiones de cada una (en lugar de solo una) y volví a ejecutar las pruebas:

Los resultados fueron similares (tenga en cuenta que hubo ligeras variaciones en cada prueba). El filtro CSS fue 0,1 ms más lento en este caso, lo que demuestra que entre los filtros CSS, los modos de fusión y los filtros SVG, los resultados no son concluyentes para el método más rápido. Sin embargo, HTML5 <canvas> quedó notablemente rezagado en comparación.

Echando un vistazo más profundo al tiempo de carga de la página a través del procesamiento de JavaScript y el tiempo de procesamiento de pintura, puede ver que esta tendencia continúa.

(Ver versión grande)
Tipo de filtro Hora de renderizar Hora de pintar
Filtro CSS 12,94 ms 4,28 ms
Modo de fusión CSS 12,10 ms 4,45 ms
Filtro SVG 14,77 ms 5,80 ms
Filtro de lienzo 15,23 ms 10,73 ms

Una vez más, <canvas> tomó más tiempo para renderizar y pintar, mientras que las dos opciones de CSS fueron las más rápidas, con SVG en el medio.

Estos resultados tienen sentido, porque <canvas> toma cada píxel individual y realiza una operación en él antes de que podamos ver ninguna imagen. Esto requiere mucha potencia de procesamiento en el momento del renderizado. Si bien normalmente los SVG se usan para gráficos vectoriales, aún los recomendaría en lugar de <canvas> cuando se trate de efectos de imágenes rasterizadas. SVG no solo es más rápido, sino que también es mucho más fácil de manejar y más flexible dentro del DOM. En general, los filtros CSS están incluso más optimizados que los filtros SVG, ya que históricamente son accesos directos que surgen de los filtros SVG y, por lo tanto, se optimizan en los navegadores.

#sin filtro

¿Qué pasa con no usar filtro? Comparé nuestro método general más rápido (agregar un filtro CSS) para editar su imagen en un software de edición de fotos antes de cargarla (utilicé Vista previa en Mac OS X para eliminar la saturación). Al preeditar la imagen, encontré una mejora constante del rendimiento de 0,1 ms en mis pruebas:

Conclusión

Los filtros de imagen son una forma divertida y efectiva de proporcionar unidad visual y atractivo estético en la web. Tenga en cuenta que vienen con un ligero impacto en el rendimiento, pero también con los beneficios de un diseño rápido en el navegador y la oportunidad de diseñar interacciones.

Para efectos de imagen simples, use filtros CSS, ya que tienen el soporte más amplio y el uso más simple. Para efectos de imagen más complejos, consulte los filtros SVG o los modos de fusión CSS. Los efectos de filtro SVG son particularmente agradables debido a sus capacidades de manipulación de canales y feColorMatrix . Los modos de mezcla CSS también ofrecen algunos efectos visuales realmente agradables con elementos superpuestos en la página. Puede usar modos de mezcla similares dentro de SVG (como feBlend ), aunque son similares a CSS background-blend-mode en el sentido de que la interacción se relaciona con el SVG en sí y no con los elementos circundantes, como permite mix-blend-mode . Simplemente no use <canvas> para filtros.