¿Qué técnica SVG funciona mejor para demasiados iconos?

Cuando comenzamos a trabajar con SVG en 2016, ocasionalmente escuchábamos una pregunta para la que nunca tuvimos una gran respuesta: ¿Qué pasa si tienes muchos íconos en una página?

aclcompanygroup - 24 Nov, 2021

¿Qué técnica SVG funciona mejor para demasiados iconos?

«SVG» Cuando comenzamos a trabajar con SVG en 2016, ocasionalmente escuchábamos una pregunta para la que nunca tuvimos una gran respuesta: ¿Qué pasa si tienes muchos íconos en una página?

Muchos asistentes estaban interesados ​​en dejar de usar fuentes de iconos. Pero si bien SVG ofrece una alternativa más accesible, confiable y poderosa, no se puede negar que a los navegadores les resulta más fácil mostrar miles de caracteres de texto que miles de imágenes (SVG o de otro tipo).

Aún así, era una pregunta fácil de esquivar. Un ícono SVG en línea típico tarda una fracción de milisegundo en procesarse: cuando le preguntaba al asistente qué tipo de interfaz requería suficientes íconos para que se sumaran, admitían que la pregunta era hipotética.
Diría algo sobre la variedad de métodos de inclusión de SVG y la importancia de las pruebas de rendimiento, los asistentes se sentirían satisfechos y todos seguiríamos adelante.

Pero luego, hace unas semanas, un cliente nos pidió que mejoremos el rendimiento de un componente que podría incluir hasta 200 filas de contenido, cada fila contiene un puñado de iconos SVG en línea. Las mejoras en las que finalmente llegaron nuestros talentosos desarrolladores del equipo de ACL Company Group y tendrían más que ver con las estrategias de manipulación DOM que con SVG, pero en el camino ofrecieron un consejo:

¿Cuál es el método más eficaz para incluir tantos iconos SVG a la vez?

Era hora de dejar de esquivar la pregunta.

A tener en cuenta

Este artículo se centra específicamente en el rendimiento de grandes cantidades de iconos SVG.

Si tiene menos de cien íconos visibles a la vez, probablemente no necesite sudar demasiado su técnica: las diferencias entre una técnica y otra son una fracción de milisegundo por ícono.

Los iconos son solo uno de los muchos casos de uso de SVG, algunos exigen una mayor complejidad y sus propias consideraciones de rendimiento. Para ver un gran ejemplo de eso, consulte el artículo de Georgi Nikoloff sobre gráficos SVG.

No compararemos el rendimiento de SVG con otros formatos de imagen o paquetes.

Todos estos íconos pueden indicar problemas de diseño más profundos. Puede depender demasiado de la iconografía para comunicar conceptos clave o componer demasiados elementos en un pergamino largo donde la paginación podría ser preferible.

SVG en línea

Un SVG en línea es solo un elemento SVG HTML con su contenido (rutas, etc.) incluido directamente dentro. No hay una estrategia elegante de agrupación o sprite aquí: si el ícono aparece muchas veces en la misma página, su contenido se repite cada vez.

<svg viewBox="0 0 24 24" width="24" height="24">
<!-- paths, shapes, etc. -->
</svg>

Para los íconos optimizados, SVG en línea fue consistentemente una de las técnicas de mayor rendimiento. Pero para los iconos no optimizados, a menudo era el más lento.

Sprite de símbolo para SVG

En esta técnica, los datos visuales reales de cada icono se representan como un símbolo elemento dentro de un solo SVG. Los iconos individuales se muestran a través de un elemento use que hace referencia al deseado symbol.

<svg style="display:none">
<symbol id="example" viewBox="0 0 24 24" width="24" height="24">
<!-- paths, shapes, etc. -->
</symbol>
</svg>
<svg><use href="#example"/></svg>

El rendimiento de esta técnica en relación con Inline SVG parece depender del número total de elementos reducidos. Para los íconos optimizados, esta técnica siempre fue más lenta. Para los íconos no optimizados, a menudo era más rápido (aunque no de manera consistente).

Sprite de símbolo externo para SVG

También probamos una variación de la técnica anterior donde los elementos symbol que se almacenan en un archivo SVG externo:

<svg><use href="path/to/sprite.svg#example"/></svg>

Los resultados variaron enormemente entre los navegadores. En Safari, los sprites de símbolos externos superan a cualquier otra técnica independientemente de la optimización. En Firefox y Samsung Internet Browser, los sprites externos superaron modestamente a los sprites en la página. Pero en Chrome y Edge, los sprites de símbolos externos eran, con mucho, la técnica más lenta (y a menudo la más inconsistente).

Elemento de imagen

Como todos los formatos de imagen, los archivos SVG se pueden mostrar usando elementos img.

<img src="path/to/icon/color.svg" alt="">

Debido a que el SVG es externo, su contenido no puede heredar los colores de la página de la misma manera que las técnicas anteriores. Para nuestras pruebas, generamos variaciones de color estáticas de todos los íconos, pero esto también podría lograrse usando un microservicio (como este).

También hay ligeras diferencias en cómo se procesan los elementos de la imagen en comparación con SVG en línea: el espacio negativo aparece ligeramente disminuido. Esto será cierto para todas las técnicas restantes de este artículo.

Esta fue una de las técnicas de mayor rendimiento, independientemente del navegador o la optimización. Dicho esto, SVG en línea tiene una ligera ventaja cuando los íconos fueron optimizados, y ambas técnicas fueron superadas constantemente por nuestra siguiente opción.

Elemento de imagen con URI de datos

Debido a que los SVG se componen de marcado en lugar de datos de mapa de bits, se pueden convertir de manera eficiente a una cadena de URI de datos sin codificación base64. Esto puede usarse para generar dinámicamente y/o colorear un elemento SVG sin requerir un servicio externo (o cargar un archivo separado).

<img src="data:image/svg+xml,..." alt="">

En todos los navegadores e independientemente de la optimización, esta técnica es la más rápida y con la menor desviación.

Elemento de imagen con filtro CSS

Los elementos img monocromáticos se pueden colorear mediante una serie de filtros CSS, como lo demostró Barrett Sonntag. Para empezar, esto requiere menos imágenes únicas o cadenas de URI de datos.

<img src="path/to/icon.svg" style="filter: ..." alt="">

Esta técnica mostró un rendimiento admirable en Chrome y Edge, un rendimiento medio en Firefox y Samsung Internet y un rendimiento decepcionante en Safari.

See the Pen
CSS filter generator to convert from black to target hex color
by Barrett Sonntag (@sosuke)
on CodePen.

Imagen de fondo

Al igual que otros formatos de imagen, los elementos SVG se pueden mostrar como elementos HTML background-image:

<div style="background-image: url(path/to/icon/color.svg);">...</div>

Las imágenes de fondo están sujetas a las mismas limitaciones que img, con diferencias de reproducción comparables. Desafortunadamente, no producen beneficios de rendimiento comparables, con un rendimiento constantemente inferior al del elemento de imagen y el elemento de imagen con técnicas de URI de datos .

También probamos esto con un URI de datos, que funcionó un poco peor:

<div style="background-image: url(data:image/svg+xml;charset=UTF-8,...);">...</div>

Y con los filtros, que funcionaron significativamente peor:

<div style="
background-image: url(path/to/icon.svg);
filter: ...;">...</div>

Imagen de máscara

Las imágenes monocromáticas se pueden utilizar como valor de a mask-image, reduciendo el área visible del elemento con estilo a la del icono. Esto conserva la capacidad de heredar los colores CSS mientras mantiene el icono en un archivo separado.

<div style="
-webkit-mask-image: url(path/to/icon.svg);
mask-image: url(path/to/icon.svg);">
...
</div>

Ya sea usando una imagen estática o un URI de datos, esta fue generalmente la técnica más lenta.

Expresiones de gratitud

Fuente para inspiración: Cloudfour