BundlesCDN - CDNFallBack

Bundles, minificación y CDN en ASP.NET MVC

Cuando empezamos a pensar nuestra aplicación para que funcione en un ambiente productivo con usuarios finales, siempre desearemos que el funcionamiento sea el mejor posible. Uno de los puntos importantes para lograr esto es que el tiempo de carga de la página en el navegador del cliente sea el menor posible.

Para lograr este objetivo en ASP.NET MVC contamos con tres conceptos que trabajan en conjunto: bundle, minificación y CDN.
El objetivo del bundle es agrupar varios archivos (tanto de scripts JavaScript como hojas de estilo CSS) en un mismo archivo. Con esto se logra perder menos tiempo en establecer la conexión para descargar cada archivo individual. A su vez, los navegadores restringen cantidad de elementos a descargar por dominio en simultáneo, agrupando varios juntos y mejorando la performance de carga.
La minificación en cambio tiene el objetivo de sacar todos aquellos espacios en blanco, comentarios y todo aquello que no sea necesario para la ejecución de un script o el agregado de una hoja de estilos. Con esto se logra una gran reducción de los tiempos de carga individuales de cada archivo. A su vez, para el caso de los scripts también ofrece ofuscación, ya que reemplaza los nombres de las variables por otros equivalentes pero con solo uno o dos caracteres.

Para entender de forma completa estos dos conceptos (además de no repetir una explicación bien) les recomiendo la lectura del post ASP.NET MVC 4 – Minification and Bundling de mi amigo Sebastián Henzenn donde, como siempre nos tiene acostumbrados, explica de forma clara y con ejemplos prácticos ambos conceptos y su utilidad.

Complementando un poco lo descripto allí, otra de las cosas que podemos hacer es anexar el uso de CDN para determinados scripts y hojas de estilo. Los CDN son servidores de contenido replicados en distintas ubicaciones, cuyo objetivo es servir contenido estático. Una de las grandes ventajas que nos ofrece es tener el contenido replicado geográficamente en distintas zonas geográficas, lo cual permite que el contenido esté lo más cerca posible de los usuarios. Esto produce una reducción mayor en los tiempos de carga, adicionalmente que deja en el servidor de nuestra aplicación la única responsabilidad de servir contenido dinámico y no archivos estáticos.

Agregar a nuestra aplicación el uso de CDN’s en relación a los bundles es muy sencillo.
Primero debemos buscar el CDN a elección de las librerías que usemos en nuestra aplicación (o las direcciones de los CDN que contratemos para subir nuestros propios recursos estáticos).
Luego debemos ir a la clase BundleConfig (ubicada en ~/App_Start/BundleConfig.cs) y agregar en el bundle que querramos el CDN correspondiente. En este caso, aplicaremos el CDN a la librería de jQuery de la siguiente forma:

BundlesCDN - AgregarCDNScript
Definición del CDN para jQuery

Ahora vamos a probar que obtenga el recurso utilizando el CDN, para lo que activaremos su uso desde la misma clase BundleConfig. Para ello agregaremos al final la siguiente línea:

BundlesCDN - ActivarCDN
Activación del uso de CDN en los bundles

Ahora si ejecutamos la aplicación y abrimos la consola de red, veremos estos resultados:

BundlesCDN - RedDescargaCDN
Descarga desde el CDN definido

Efectivamente se está realizando la utilización del CDN definido. Aunque en este caso vemos que el tiempo de demora es mayor que los otros archivos, esto es particular por estar ejecutando la aplicación sobre localhost.

Aunque en este caso estamos usando CDN para scripts JavaScript, lo mismo se puede realizar para hojas de estilo CSS. Para ambos casos cabe recordar que los archivos que decidamos combinar en un solo bundle deben poder reemplazarse en forma conjunta por un archivo equivalente en un CDN. Sino, estaremos dejando nuestra aplicación con funcionalidad inconsistente.

Como la mayoría de las cosas, el uso de CDN también tiene una desventaja. Aunque los servidores donde se aloja dicho contenido se caracterizan por tener una alta disponibilidad, los mismos pueden estar fuera de servicio en determinados casos, privando a nuestra aplicación de funcionalidades (lo que podría ocasionar errores de todo tipo, desde visualización a inconsistencia de datos). Afortunadamente para los archivos JavaScript tenemos una solución elegante para solucionar este posible inconveniente y garantizar siempre un buen tiempo de carga sin resignar fiabilidad.

Para ello debemos contar con una expresión de validación que determina si el script (y por consiguiente su funcionalidad) ha sido correctamente cargado. La misma evaluará de forma condicional la igualdad con undefined, siendo un resultado positivo que el script no se ha cargado correctamente. Para el caso de jQuery, la expresión a validar es window.jQuery. Generalmente todas las librerías cuentan con una función u objeto para validar que la carga haya sido correcta.

Para aplicar esta validación, lo que debemos hacer es indicarle al bundle en cuestión la expresión de validación en la propiedad CdnFallbackExpression:

BundlesCDN - CDNFallBack
Definición del FallBack para jQuery

Si ahora ejecutamos la aplicación nuevamente, veremos que falla la descarga del CDN (cuyo nombre está mal escrito intencionalmente), pero el script se descarga desde el servidor local (mediante el bundle generado):

BundlesCDN - DescargaFallBack
Descarga alternativa al fallar el CDN

Aunque parezca sencillo esto es un beneficio importante, ya que si está disponible el CDN contamos con el acceso rápido y externo a nuestro servidor. Pero para aquellos casos (debería ser baja la probabilidad de que suceda) en los que no está disponible el CDN, nuestro servidor entregará los archivos según lo configurado en el bundle original y con la minificación aplicada.

Esta alternativa en particular lo que termina generando finalmente es un script en la página en cuestión en el navegador, la cual luego de descargar el archivo desde el CDN valida la expresión que le indicamos. Si el resultado de la misma es positivo (o sea que es igual a undefined) aplicará el bundle generado localmente:

BundlesCDN - ScriptValidacion
Script de validación generado automáticamente

Obviamente que podemos realizar la generación de este script por nuestra cuenta, pero usando las funcionalidades brindadas por ASP.NET MVC nos garantizamos un correcto funcionamiento. Personalmente, también considero que esta alternativa logra un resultado mucho más ordenado y prolijo, en vez de tener en las vistas muchos scripts para validar la carga. Además de perder la relación con los bundles generados.

Espero que les sea útil, y lo puedan implementar en sus proyectos para darles un plus de rendimiento y fiabilidad.

Gracias por leer!

Anuncios

2 comentarios en “Bundles, minificación y CDN en ASP.NET MVC

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s