Tengo una aplicación ASP.NET WebForms 4.8 que muestra imágenes en un GridView. Los usuarios navegan rápidamente entre registros utilizando el teclado para visualizar las imágenes.
Situación actualLas imágenes se enviaban al navegador codificadas en Base64 dentro del HTML:
<img src="data:image/jpeg;base64,..." />
Problemas detectados:
Las imágenes se sirven mediante un Handler (.ashx):
¿Qué mejoras recomendaríais para optimizar al máximo este escenario?
Aspectos que me interesan especialmente:
ServidorLos 3 problemas más probables son:
Imágenes servidas a resolución original
Ausencia de caché HTTP
Imágenes almacenadas en Base de Datos y convertidas constantemente
el GC tendrá mucha presión.
De todas ellas, miniaturas + caché HTTP + eliminar Base64 suelen proporcionar más del 80% de la mejora de rendimiento en este tipo de aplicaciones.
¿Alguien ha tenido experiencias similares o puede compartir qué optimizaciones tuvieron mayor impacto en consumo de memoria, velocidad de carga y escalabilidad?
Lecciones aprendidas ??
En una aplicación con 20 usuarios concurrentes esto puede disparar el uso de memoria tanto en IIS como en el navegador.
Si tienes muchas imágenes en el GridView:
Los navegadores modernos soportan: loading="lazy"
Image1.Attributes.Add("loading", "lazy");
Esta mejora suele ser la que más impacto tiene.
Situación actualSupongamos:
Foto original = 4000 x 3000
Peso = 4 MB
<img width="200" height="150">
El navegador descarga igualmente los 4 MB
Generar una miniatura una única vez:
Originales/WebP suele reducir entre un 25% y un 50% respecto a JPG.
ASP.NET 4.8 no tiene soporte nativo.
La librería más habitual es:
Install-Package Magick.NET-Q8-AnyCPU
using (var image = new MagickImage(source))
image.Write(destWebp);
Muchos handlers legacy hacen esto:
Muy importante.
En tu .ashx:
context.Response.Cache.SetExpires( DateTime.Now.AddDays(30));
context.Response.Cache.SetMaxAge( TimeSpan.FromDays(30));
Así cuando el usuario recorra el GridView:
Si el usuario navega con el teclado:
Fila actual = 50
puedes precargar:
Si el GridView carga cientos de filas:
Mal:
Ordenado por impacto:
1. Eliminar Base64 ✅Tu código actual es el principal problema.
2. Miniaturas de 200-300 px ✅Mantener originales aparte.
3. Convertir miniaturas a WebP ✅Gran reducción de tráfico.
4. Handler con TransmitFile() ✅Menor memoria en IIS.
5. Caché HTTP de 30 días ✅Ahorro enorme de peticiones repetidas.
6. loading="lazy" ✅Descarga sólo lo visible.
7. Paginación del GridView ✅No renderizar cientos de imágenes a la vez.
Si tuviera que apostar, diría que el 80-90% de los problemas de memoria vienen del Base64 y de servir imágenes a resolución original.
Esas dos mejoras suelen producir la diferencia más grande en aplicaciones WebForms heredadas.