En mayo de 2022, los equipos de Aurora y Angular anunciaron que colaborarían en una directiva de imágenes para Angular. Recientemente, se lanzó la directiva para la versión preliminar para desarrolladores como parte de la versión 14.2 de Angular. En esta publicación, se explica cómo la nueva directiva de imagen, NgOptimizedImage
, admite la optimización de imágenes en Angular.
Información general
Las imágenes son un componente común y crucial de la experiencia del usuario en la Web. El 99.9% de las páginas web genera solicitudes de una o más imágenes. Las imágenes también son los factores que más contribuyen al peso de las páginas, ya que representan una mediana de 982 kilobytes por página.
Debido a su creciente cantidad y tamaño, las imágenes pueden dificultar el rendimiento de las páginas web y afectar las métricas de Métricas web esenciales. En el 79.4% de las páginas para computadoras de escritorio, una imagen fue el elemento Largest Contentful Paint (LCP) en 2021. Por lo tanto, la búsqueda de imágenes optimizadas se ha convertido en un esfuerzo constante para muchos de nosotros.
El equipo de Aurora cree en aprovechar el poder de los marcos de trabajo para proporcionar soluciones integradas a los desafíos comunes de los desarrolladores. Su primera incursión en el espacio de optimización de imágenes fue el componente de imagen de Next.js. Consideraron que este componente era un campo de prueba para determinar si mejorar la experiencia del desarrollador (DX) de la optimización de imágenes podría generar un aumento en el rendimiento de más apps que usan frameworks.
El primer conjunto de resultados del usuario de Next.js Leboncoin fue alentador. Leboncoin observó una mejora significativa en el LCP (de 2.4 s a 1.7 s) después de que empezara a usar next/image
. La posterior adopción de next/image
en la comunidad desempeñó un papel en el aumento de los orígenes de Next.js que cumplieron con los umbrales de LCP. Pronto hubo solicitudes para funciones similares en otros frameworks, y una de ellas era Angular.
Como resultado, Aurora consultó a Angular y Nuxt con el fin de crear prototipos de componentes de imagen para estos frameworks. El componente de imagen de Nuxt se lanzó el año pasado. Ahora se lanzó la directiva de imágenes de Angular (NgOptimizedImage
) para que la optimización de imágenes se adapte a Angular de manera predeterminada.
Oportunidad
Angular es uno de los frameworks de JavaScript líderes que usan los desarrolladores en la actualidad. Más de 50,000 de los orígenes rastreados por HTTPArchive lo usan en dispositivos móviles y ofrece cerca de 3 millones de descargas semanales en NPM.
Si se observan las puntuaciones de Métricas web esenciales, el porcentaje de orígenes de Angular que cumplen con los requisitos Los umbrales de LCP aún necesitan trabajo. Solo el 18.74% de los sitios de Angular tuvieron un buen LCP en dispositivos móviles en junio de 2022. Dado que las imágenes son el elemento LCP de más del 70% de las páginas web en dispositivos móviles y computadoras de escritorio, las imágenes LCP no optimizadas podrían ser una de las principales causas de un LCP más deficiente en los sitios web de Angular.
La directiva de imagen de Angular se diseñó para ayudar a mejorar estas cifras.
MVP para la directiva NgOptimizedImage
El MVP de la directiva de imágenes de Angular se basa en lecciones de los componentes de imagen que Aurora compiló hasta la fecha, a la vez que adapta el diseño a la experiencia de renderización del cliente de Angular. Muchos de los problemas de optimización de imágenes estándar se solucionaron de la siguiente manera:
- Proporcionar valores predeterminados sólidos
- Arrojar errores o advertencias para garantizar el cumplimiento de las prácticas recomendadas.
Los aspectos destacados del diseño son los siguientes:
Carga diferida inteligente
Lo ideal es que las imágenes que son invisibles para el usuario durante la carga de la página (por ejemplo, imágenes en la mitad inferior de la página o imágenes de carrusel ocultas) se carguen de forma diferida. La carga diferida libera recursos del navegador para cargar otros textos, archivos multimedia o secuencias de comandos importantes. La mayoría de las imágenes no son fundamentales y deberían cargarse de forma diferida, pero solo el 7.8% de las páginas utilizó la carga diferida nativa en 2021.
La directiva de imagen de Angular carga de forma diferida las imágenes no críticas de forma predeterminada y solo carga con anticipación las imágenes marcadas especialmente como
priority
. Esto garantiza que la mayoría de las imágenes muestren un comportamiento de carga óptimo.Priorización de imágenes fundamentales
Agregar sugerencias de recursos (p.ej.,
preload
opreconnect
) para priorizar la carga de imágenes críticas es una práctica recomendada. Sin embargo, la mayoría de las apps no las usan. Según el Almanac web de 2021, solo el 12.7% de las páginas para dispositivos móviles usa sugerencias de preconexión y solo el 22.1% de las páginas para dispositivos móviles usa sugerencias de precarga.La directiva de imagen actúa en dos frentes cuando las imágenes se marcan como prioridad.
- Establece la fetchpriority de la imagen como
"high"
para que el navegador sepa que debe descargar la imagen con una prioridad alta. - En el modo de desarrollo, una verificación del entorno de ejecución confirma que se incluyó una sugerencia del recurso
preconnect
correspondiente al origen de la imagen.
En el modo de desarrollo, la directiva también usa la API de PerformanceObserver para verificar que la imagen de LCP se haya marcado como
priority
como se esperaba. Si no está marcadopriority
, se genera un error que le indica al desarrollador que agregue el atributopriority
a la imagen LCP.En última instancia, esta combinación de automatización y cumplimiento garantiza que la imagen LCP tenga una sugerencia
preconnect
, un valor de atributofetchpriority
dehigh
y no se cargue de forma diferida.- Establece la fetchpriority de la imagen como
Configuración optimizada para herramientas de imagen populares
Se recomienda que las aplicaciones de Angular usen CDN de imágenes, que suelen proporcionar servicios de optimización de forma predeterminada.
La directiva fomenta el uso de CDN de imágenes, ya que proporciona una experiencia del desarrollador (DX) especialmente atractiva para configurarlas en la app. Admite una API de cargador que te permite definir el proveedor de CDN y la URL base en la configuración. Una vez configurado, solo tienes que definir el nombre del recurso en el lenguaje de marcado. Por ejemplo:
// in module providers: provideImgixLoader('https://mysite.net/assets/') // in markup <img ngSrc="image.png" > <img ngSrc="image2.png" >
Esto equivale a incluir las siguientes etiquetas de imágenes y reduce el lenguaje de marcado que los desarrolladores deben incluir para cada imagen.
<img src="https://mysite.net/assets/image.png"> <img src="https://mysite.net/assets/image2.png">
La directiva de imagen proporciona cargadores integrados con configuración óptima para las CDN de imágenes más populares. Estos cargadores formatearán las URLs de imagen automáticamente para garantizar que se usen los parámetros de configuración de compresión y formato de imagen recomendados para cada CDN.
Errores y advertencias integrados
Además de las optimizaciones integradas mencionadas anteriormente, la directiva también tiene verificaciones integradas para garantizar que los desarrolladores hayan seguido las prácticas recomendadas en el lenguaje de marcado de imágenes. La directiva de imagen realiza las siguientes verificaciones.
Imágenes sin tamaño: La directiva de imagen arroja un error si el lenguaje de marcado de imágenes no tiene definidos un ancho y una altura explícitos. Las imágenes sin tamaño pueden provocar cambios de diseño, lo que afecta la métrica Cambio de diseño acumulado (CLS) de la página. Para evitarlo, se recomienda que las imágenes tengan los atributos
width
yheight
especificados.Relación de aspecto: La directiva de imagen arroja un error para informar a los desarrolladores si la relación de aspecto de
width
:height
definida en el HTML no es cercana a la relación de aspecto real de la imagen renderizada. Esto puede hacer que la imagen se vea distorsionada en la pantalla. Esto puede ocurrir si- Definiste las dimensiones incorrectas (ancho o alto) por error o
- Si definiste una dimensión por porcentaje en tu CSS, pero no la otra (por ejemplo,
width: 100%
necesitaheight: auto
para asegurarse de que la imagen crezca en ambas dimensiones).
Imágenes de gran tamaño: Si la imagen no define un elemento
srcset
y la imagen intrínseca es significativamente más grande que la imagen renderizada, la directiva mostrará una advertencia que sugerirá el uso de los atributossrcset
ysizes
.Densidad de la imagen: La directiva arrojará un error si intentas incluir una imagen en
srcset
con una densidad de píxeles superior a3x
. Por lo general, no se recomiendan los descriptores con un valor superior a2x
porque tienen la consecuencia no deseada de forzar a los dispositivos móviles de alta resolución a descargar imágenes grandes. Además, el ojo humano no puede distinguir muchas diferencias superiores al doble.
Desafíos
Uno de los desafíos principales del diseño de NgOptimizedImage
fue adaptar las estrategias de optimización de imágenes para que funcionen dentro de un marco de trabajo del cliente. La experiencia de renderización predeterminada en Next.js es Server Side Rendering (SSR) o Static Site Generation (SSG), mientras que en Angular es la renderización del cliente (CSR). Aunque Angular admite una biblioteca SSR (angular/universal), la mayoría de las apps de Angular (alrededor del 60%) usan CSR.
La directiva de imagen se creó completamente para que el CSR se alinee con el caso de uso típico en las apps de Angular. Esto estableció restricciones adicionales, y el equipo tuvo que repensar cómo compilar optimizaciones específicas para las aplicaciones de CSR.
Estos son algunos de los desafíos que se encontraron:
Sugerencias de recursos de asistencia
La precarga de recursos críticos ayuda al navegador a descubrirlos antes. Sin embargo, incluir sugerencias de recursos en las apps de Angular es complicado por los siguientes motivos:
Adición manual: Es difícil para los desarrolladores agregar la sugerencia del recurso
preload
de forma manual. Angular usa un archivo index.html compartido para todo el proyecto o para todas las rutas del sitio web. Por lo tanto, el<head>
del documento es el mismo para todas las rutas (al menos al momento de la entrega). Agregar cualquier sugerencia depreload
a<head>
implicaría que el recurso se precargaría para todas las rutas, incluso en las que no es obligatorio. Por lo tanto, no se recomienda agregar sugerencias depreload
de forma manual.Agregación automática durante la renderización: No se recomienda usar el framework para agregar sugerencias de precarga al encabezado del documento durante la renderización en una app de CSR. Dado que la renderización ocurre después de que se descarga y ejecuta JavaScript, el
<head>
se renderizará demasiado tarde para no tener ningún valor.En la primera versión de la directiva, sirve una combinación de sugerencias
preconnect
yfetchpriority
para priorizar la imagen en lugar depreload
. Sin embargo, actualmente Aurora está trabajando con el equipo de la CLI de Angular para habilitar la inserción automática de sugerencias de recursos en el tiempo de compilación. ¡Mantente alerta!Optimiza el tamaño y el formato de la imagen en el servidor
Como las apps de Angular suelen renderizarse del cliente, las imágenes del sistema de archivos no se pueden comprimir en el momento de la solicitud y se entregan tal cual. Por este motivo, se recomienda usar CDN de imágenes para comprimir las imágenes y convertirlas a formatos modernos como WebP o AVIF on demand.
Si bien la directiva no aplica de manera forzosa el uso de CDN de imágenes, te recomendamos que las uses con la directiva, y sus cargadores integrados garantizan que se usen las opciones de configuración correctas.
Impacto
En la siguiente demostración, se muestra la diferencia que la directiva de imágenes de Angular puede marcar en el rendimiento de las imágenes. Compara dos sitios web:
Website One: Usa elementos <img>
nativos con imágenes entregadas a través de la CDN de Imgix (con opciones de configuración predeterminadas).
Sitio web dos: Usa la directiva de imagen para todas las imágenes. También incluye las optimizaciones que recomiendan directamente las advertencias o los errores que arroja la directiva.
El equipo trabajó con socios para validar el impacto de la directiva de imagen en el rendimiento en las aplicaciones empresariales reales de Angular.
Uno de estos socios fue Land's End. Se esperaba que su sitio fuera un buen caso de prueba de resultados que podrían ver las aplicaciones reales.
Se realizaron pruebas de laboratorio con Lighthouse en su entorno de QA antes y después de usar la directiva de imagen. En computadoras, el LCP medio disminuyó de 12.0 s a 3.0 s, una mejora del 75% en el LCP. En dispositivos móviles, el LCP medio disminuyó de 20.2 s a 12.0 s (mejora del 40.6%).
Hoja de ruta para el futuro
Esta es solo la primera parte del diseño de la directiva de imagen de Angular. Hay muchas otras funciones planificadas para versiones futuras, incluidas las siguientes:
Mejor compatibilidad con imágenes responsivas:
Actualmente,
NgOptimizedImage
admite el uso desrcset
, pero los atributossrcset
ysizes
deben proporcionarse de forma manual para cada imagen. En el futuro, la directiva podría generar los atributossrcset
ysizes
automáticamente.Inserción automática de sugerencias de recursos
Podría ser posible realizar la integración con la CLI de Angular a fin de generar etiquetas de conexión previa y precarga para imágenes de LCP críticas.
Compatibilidad con el SSR de Angular
La versión de MVP se diseñó teniendo en cuenta las restricciones de la CSR de Angular, pero también será importante explorar soluciones de optimización de imágenes para el SSR de Angular (angular/universal).
Mejoras en la experiencia del desarrollador
NgOptimizedImage
requiere que se especifiquen los atributoswidth
yheight
para cada imagen. Sin embargo, especificarlas para cada imagen puede resultar tedioso para algunos desarrolladores. Existe el potencial de mejorar la experiencia del desarrollador en la próxima iteración de la siguiente manera:- Admite un modo adicional (similar a la opción de diseño de imagen de "
fill
" en Next.js) que no requiere que se defina el ancho o la altura explícitos. - Usa la integración de la CLI para establecer automáticamente el ancho y la altura de las imágenes locales mediante la determinación de las dimensiones reales de la imagen.
- Admite un modo adicional (similar a la opción de diseño de imagen de "
Conclusión
La directiva de imágenes de Angular estará disponible para los desarrolladores en etapas a partir de la versión preliminar para desarrolladores, que se encuentra en la versión 14.2.0. Prueba NgOptimizedImage
y envíanos tus comentarios
Agradecemos especialmente a Katie Hempenius y Alex Castle por su contribución.