El otro día os comentaba las diferencias entre los proyectos de tipo Sitio Web y Aplicación Web en Visual Studio, y las implicaciones que ello tenía a la hora de trabajar, para ayudaros a decidir entre uno u otro.

Una de las "pegas" que le ponía al modelo de sitios Web era que al generarse una DLL por cada página y control, al final podíamos acabar con problemas de rendimiento por tener que haber cargado todas esas DLL en el proceso de la aplicación.

He puesto "pegas" entre comillas porque realmente desde mi punto de vista esta posible situación más que un problema es un exotismo, puesto que no me imagino ninguna aplicación Web realista que tenga miles de páginas (hablo de varios miles) y que no esté dotada del agún mecanismo de generación automática de páginas.

De hecho el único sistema que he visto que pudiera provocar esta situación es un sistema gestor de contenidos creado para un organismo oficial por una conocida empresa de consultoría (de cuyo nombre no quiero acordarme) y que se dedicaba a generar como páginas ASPX cada una de las páginas de contenidos que los usuarios iban creando. En mi opinión el proyecto no estaba demasiado bien hecho ni concebido (y no lo digo solo por este detalle) y desde luego para este caso concreto podrían haber aplicado otro tipo de técnicas para generar los contenidos de forma dinámica con alto rendimiento igualmente.

En cualquier caso. Este proyecto tenía miles de páginas generadas cuyos ensamblados que se iban cargando en memoria y degradando a largo plazo el rendimiento de la aplicación. Todas estas páginas de contenidos realmente no ejecutaban código alguno sino que se limitaban a mostrar HTML y, en algunos casos, etiquetas de tipo <% %> con alguna información.

¿Cómo podían evitar este problema de degradación del rendimiento?

La gente del equipo de ASP.NET consciente de esta posible situación indeseable la tuvieron en cuenta y diseñaron un ajuste que se le puede hacer a las páginas para evitar que se compilen. Se trata de la opción CompilationMode.

Este atributo se puede establecer en la directiva de cada página o control y puede tomar los siguientes valores:

· Always: las página o control se compilan siempre, y por lo tanto se genera un ensamblado.
· Never: no se compila, por lo que no se genera un ensamblado y no hay que cargarla en memoria.
· Auto: es ASP.NET en tiempo de ejecución quien decide si la página se compila o no, dando preferencia a que no se compile si no es necesario.

Así, por ejemplo, podemos definir en la directiva de una página lo siguiente para evitar su compilación:

<%@ Page CompilationMode="Auto" %>

(Nota: no se admiten en la directiva de página los atributos CodeFile, AutoEventWireup o Inherits, porque no se genera código para la página)

En estas condiciones sólo se permite la interpretación en tiempo de ejecución de etiquetas de tipo <%# %> o <%$ %>, pero no otro tipo de código como eventos de página. Estas etiquetas de sintaxis declarativa de ASP.NET permiten utilizar bindings a datos (ej: <%# Bind(...) %> o <%# Eval(...) %>) y también otro tipo de expresiones declarativas como sustitución de recursos de localización o cadenas de conexión en controles enlazados, sin necesidad de generar código relacionado y compilarlo.

Así, por ejemplo, podemos escribir instrucciones como esta:

<asp:Label ID="Label1" runat="server" Text="<%$ Resources:Recursos, Saludo %>"></asp:Label>

aunque la pongamos en modo de comilación "Never" para que no se genere el ensamblado, y todo funcionará correctamente. Si metemos cualquier tipo de código en la página se producirá un error al intentar compilar la aplicación desde Visual Studio.

Así, en el ejemplo de páginas generadas que lo único que hacían era mostrar contenido pre-generado (o incluso aunque éste fuera sacado de una base de datos con una expresión de enlazado del tipo <%# %>), si le ponemos este atributo CompilationMode a Never conseguiremos que no se genere ni se cargue en memoeria el ensamblado de la página, y un consiguiente aumento de rendimiento, tal y como se indica en la documentación.

Configurar el modo de compilación globalmente

Siguendo con nuestro ejemplo de páginas generadas, si éstas se almacenan todas dentro de una misma carpeta o en una estructura de carpetas que cuelguen de una única carpeta raíz, es posible definir el modo de compilación para todas ellas al mismo tiempo usando el archivo web.config:

De este modo podemos establecer el modo al mismo tiempo para todas las páginas que bajo la influencia de este web.config y no tenemos que establecerlo una por una.

Hay que tener cuidado que en ninguna de las carpetas que se ven afectadas haya páginas que sí contengan código o fallará la compilación del proyecto. También hay que tener cuidado si alguna de ellas utiliza una Master Page que tenga código, pues surgirán conflictos también.

En resumen

Para casos muy particulares de sitios enormes en los que necesitemos asegurar que no degradamos el rendimiento, esta técnica poco conocida puede resultarnos de gran ayuda. Tenla en cuenta si te encuentras algo así.

¡Espero que te sea útil!

💪🏻 ¿Este post te ha ayudado?, ¿has aprendido algo nuevo?
Pues NO te pido que me invites a un café... Te pido algo más fácil y mucho mejor