Agrupar y minimizar recursos estáticos en ASP.NET Core

Por Scott Addie y David Pine

En este artículo se explican las ventajas de aplicar la agrupación y la minimización, así como la forma en que estas características se pueden utilizar con aplicaciones web de ASP.NET Core.

¿Qué es el empaquetado y la minificación?

El empaquetado y la minimización son dos optimizaciones de rendimiento distintas que se pueden aplicar en una aplicación web. Usadas de forma conjunta, el empaquetado y la minimización mejoran el rendimiento al reducir el número de solicitudes al servidor y el tamaño de los recursos estáticos solicitados.

El empaquetado y la minificación mejoran principalmente el tiempo de carga de la primera solicitud de página. Una vez solicitada una página web, el explorador almacena en caché los recursos estáticos (JavaScript, CSS e imágenes). Por lo tanto, la agrupación y la minimización no mejoran el rendimiento al solicitar la misma página, o páginas, en el mismo sitio, al solicitar los mismos recursos. Si el encabezado Expires no se establece correctamente en los recursos y no se usa el empaquetado ni la minificación, las heurísticas de vigencia del explorador marcan los recursos como obsoletos al cabo de unos días. Además, el explorador requiere una solicitud de validación para cada recurso. En este caso, la agrupación y la minimización proporcionan una mejora del rendimiento incluso después de la solicitud de la primera página.

Unión

La agrupación combina varios archivos en un único archivo. La agrupación reduce el número de solicitudes de servidor necesarias para representar un recurso web, como una página web. Puede crear cualquier número de conjuntos individuales específicamente para CSS, JavaScript, etc. Menos archivos son menos solicitudes HTTP del explorador al servidor, o del servicio que proporciona la aplicación. Esto tiene como resultado una mejora en el rendimiento de la carga de la primera página.

Minificación

La minimización quita caracteres innecesarios del código sin modificar la funcionalidad. El resultado es una reducción significativa del tamaño de los recursos solicitados (tales como CSS, imágenes y archivos de JavaScript). Entre los efectos comunes de la minificación se incluyen la reducción de nombres de variable a un carácter y la eliminación de comentarios y espacios en blanco innecesarios.

Considere la siguiente función de JavaScript:

AddAltToImg = function (imageTagAndImageID, imageContext) {
  ///<signature>
  ///<summary> Adds an alt tab to the image
  // </summary>
  //<param name="imgElement" type="String">The image selector.</param>
  //<param name="ContextForImage" type="String">The image context.</param>
  ///</signature>
  var imageElement = $(imageTagAndImageID, imageContext);
  imageElement.attr('alt', imageElement.attr('id').replace(/ID/, ''));
}

La minimización reduce la función a lo siguiente:

AddAltToImg=function(t,a){var r=$(t,a);r.attr("alt",r.attr("id").replace(/ID/,""))};

Además de quitar los comentarios y los espacios en blanco innecesarios, se ha cambiado el nombre de los siguientes parámetros y variables de la siguiente manera:

Original Renombrado
imageTagAndImageID t
imageContext a
imageElement r

Impacto de la unión y la minimización

En la tabla siguiente se describen las diferencias entre la carga de recursos de forma individual y el uso del empaquetado y la minimización para una aplicación web típica.

Acción Sin U/M Con U/M Reducción
Solicitudes de archivos 18 7 61 %
Bytes transferidos (KB) 265 156 41 %
Tiempo de carga (ms) 2360 885 63 %

Aunque ha mejorado el tiempo de carga, este ejemplo se ha ejecutado localmente. Se obtienen mayores mejoras de rendimiento al usar el empaquetado y la minimización con recursos transferidos a través de una red.

La aplicación de prueba que se usa para generar las cifras de la tabla anterior muestra mejoras típicas que podrían no aplicarse a una aplicación determinada. Se recomienda probar una aplicación para determinar si la unión y la minimización producen una mejora del tiempo de carga.

Elección de una estrategia de unión y minimización

ASP.NET Core no proporciona una solución nativa de agrupación y minificación. Herramientas de terceros como Gulp y Webpack proporcionan automatización de flujos de trabajo para el empaquetado y la minificación, así como optimización de imágenes y linting. El empaquetado y la minificación antes del despliegue proporcionan la ventaja de reducir la carga del servidor. Sin embargo, la agrupación y la minificación aumentan la complejidad de la compilación y solo funcionan con archivos estáticos.

Empaquetado y minimización basados en el entorno

Como procedimiento recomendado, los archivos empaquetados y minimizados de la aplicación deben usarse en un entorno de producción. Durante el desarrollo, los archivos originales facilitan la depuración de la aplicación.

Especifique los archivos que se van a incluir en las páginas mediante el Environment Tag Helper en las vistas. El Asistente de etiquetas de entorno solo representa su contenido cuando se ejecuta en entornos concretos.

La siguiente etiqueta environment renderiza los archivos CSS no procesados cuando se ejecuta en el entorno Development:

<environment include="Development">
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
    <link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment names="Staging,Production">
    <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
          asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
          asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>

La siguiente etiqueta environment muestra los archivos CSS unidos y minimizados cuando se ejecuta en un entorno distinto de Development. Por ejemplo, la ejecución en Production o Staging desencadena la representación de estas hojas de estilo:

<environment exclude="Development">
    <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
          asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
          asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
<environment names="Staging,Production">
    <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
          asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
          asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
    <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>