Blog Jose Cullar

//Agilist, Tech Lead, Full Stack Developer & Life-long learner

Optimizando el rendimiento de ASP .net

por Jose el 1 abril, 2010

  • Minimiza las peticiones cliente/servidor
    Se puede mejorar el rendimiento de la página y la experiencia del usuario si no se utiliza código que produzca acciones de ida y vuelta en el servidor. Hay circunstancias en las que no es necesario utilizar los controles de servidor ASP.NET ni controlar los eventos de devolución de datos. A la hora de realizar algún tipo de desarrollo debemos tener claro el alto coste que supone viajar al servidor. Además, si ViewState se encuentra activado, ASP.NET guardará todo el estado de los controles existentes disminuyendo el rendimiento y la velocidad de carga considerablemente. La ejecución en el cliente es la respuesta.
    Amplía esta información aquí.


  • Utiliza la propiedad IsPostBack del objeto Page para evitar ejecuciones innecesarias en acciones de ida y vuelta al servidor
    Normalmente en los eventos de Page_Init o Page_Load, se realizan ciertas acciones de inicialización y carga. Evalúa qué código requiere que se ejecute sólo en la primera carga y cuales deben ejecutarse siempre por cada petición. De este modo la ejecución siempre será sólo de aquello que se necesite. Utiliza la propiedad Page.IsPostBack para excluir y englobar el código que se ejecutará sólo en la primera carga.
    Amplía esta información aquí.

  • Guarda el estado de vista del control de servidor sólo cuando sea necesario
    Para deshabilitar o habilitar el estado de vista del control establece el atributo EnableViewState sobre el propio control o en la directiva Page con el valor False o True.
    Con esta propiedad activada, ASP.NET se encarga automáticamente de recopilar el estado de todos los controles de la página para generar un valor encriptado y guardarlo en un INPUT HIDDEN llamado __VIEWSTATE de la página. De este modo siempre mantiene el estado y datos de todos los controles entre peticiones al servidor. Para una aplicación de alto rendimiento es recomendable desactivar siempre, o casi siempre, esta propiedad. De este modo evitamos la encriptación/desencriptación del estado de los controles y la transferencia del valor encriptado entre el cliente y servidor (que dependiendo de los controles que añadas puede llegar a ser muy pesado) mejorando el rendimiento y la velocidad de carga.
    Amplía esta información aquí.

    Aún si se necesite tener el ViewState activado pueden realizarse acciones para optimizar el rendimiento:

    • Existen funcionalidades para comprimir el ViewState. Minimizando y reduciendo el tamaño de éste mejorando el tiempo de carga y recepción de datos entre el cliente/servidor.
    • Mueve el Viewstate al final de la página (INPUT HIDDEN) para no incluirlo en el inicio del documento (por defecto), mejorando la velocidad de carga.
  • Mantén el almacenamiento en búfer activado a menos que tengas razones para desactivarlo. Deshabilitar el almacenamiento en búfer en las páginas Web ASP.NET representa un costo de rendimiento significativo.
    Con el Búfer activo, el servidor web no devuelve datos hasta que no haya finalizado la ejecución de toda la página. Con el Búfer desactivado realiza procesos de ejecución y respuesta hasta la finalización total de la respuesta. Es decir, con el búfer desactivado el servidor web requerirá más recursos para generar la devolución de datos para una misma petición, disminuyendo en gran medida el rendimiento. Una buena opción es activar siempre el Búfer y controlar manualmente la devolución de datos, aunque no se haya ejecutado aún la totalidad de la página, mediante Response.Flush(). La opción de Búfer también debe activarse en el Servidor Web.
    Amplía esta información aquí

  • Utiliza Server.Transfer, en vez de Response.Redirect o Response.RedirectPermanent (ASP .net 4.0) en el redireccionamiento entre páginas ASP.NET dentro de una misma aplicación web
    Para la redirección es aconsejable por temas de rendimiento utilizar Server.Transfer ya que no se envían nuevamente las cabeceras para la redirección (siempre y cuando no se requiera enviar nuevas cabeceras según tipo de redirección).
    Amplía esta información aquí.

  • Deshabilita el estado de sesión cuando no lo utilices
    No todas las aplicaciones o páginas requieren el estado de sesión por usuario; deshabilita el estado de sesión si no es necesario.

    • Si en determinadas páginas no se utilizan variables de sesión: Desactiva la funcionalidad especificando el atributo EnableSessionSate a False en la directiva Page.
    • Si en determinadas páginas sólo se utilizan variables de sesión para lectura: Activa la funcionalidad especificando el atributo EnableSessionSate a ReadOnly en la directiva Page.
    • Si necesitas disponer de lectura y modificación de variables en sesión: Activa la funcionalidad especificando el atributo EnableSessionSate a True en la directiva Page.

    Una opción es guardar los datos de sesión del usuario en cookies que se almacenan en el navegador del usuario especificándoles un valor para su caducidad.

    Sesión en escenarios balanceados:
    Normalmente las aplicaciones de alto rendimiento se encuentran balanceadas en varios servidores o varios workers dentro de un mismo servidor, o ambas.
    Teniendo en cuenta que el tipo por defecto para la sesión de usuario es en memoria en el servidor, no nos serviría en dichos escenarios.
    Lo común en estos escenarios es el guardado de la sesión en SQL Server (sobre una base de datos central) o en un proceso de .NET aspnet_state.exe compartido en un único servidor, o en cada server (compartido por workers).
    Si los servidores responden por afinidad (siempre el mismo servidor al mismo usuario durante el transcurso de peticiones durante la sesión), podemos utilizar cualquier tipo de guardado de sesión (siempre teniendo presente las ventajas e inconvenientes de cada uno).
    Amplía esta información sobre los modos de sesión aquí.
    Amplía esta información sobre el atributo EnableSessionState aquí.

  • Utiliza procedimientos almacenados para el acceso a los datos
    El rendimiento mejorará si empleas, siempre que sea posible, procedimientos almacenados compilados en lugar de comandos SQL. Además proporciona encapsulación del código SQL en los procedimientos almacenados evitando el HardCode en el código, dificultando la reutilización y escalabilidad.

  • Utiliza SqlDataReader para la lectura de datos sobre una determinada conexión sobre la base de datos.
    En los casos en los que sólo necesites recuperar datos para mostrarlos o guardarlos en objetos complejos propios para el tratamiento de lógica de negocio, la clase SqlDataReader proporciona un mayor rendimiento que la clase DataSet/DataTable. Las colecciones DataSet son colecciones desconectadas de la base de datos, se almacenan en memoria, aumentando el consumo de la memoria y utilizando grandes consumos de CPU. Utiliza sólo DataTable cuando se priorice la duración de la conexión sobre la base de datos, es decir, cuando necesites colecciones de forma desconectada. O te enfrentes a requerimientos que te impongan la utilización las funcionalidades que ofrecen las colecciones DataSet.
    Amplía esta información sobre SqlDataReader aquí.
    Amplía esta información sobre DataSet aquí.

  • Guarda en caché los datos y los resultados de página siempre que sea posible
    ASP.NET ofrece mecanismos para almacenar en caché los resultados de página (OutputCache) o datos (Caché) cuando no tienen que calcularse dinámicamente para cada solicitud de página. Además, el diseño de las solicitudes de páginas y de datos que puedan almacenarse en caché, especialmente en las áreas del sitio en las que se espere mayor tráfico, puede optimizar el rendimiento de las páginas. Si utilizas la caché correctamente, el rendimiento de su sitio mejorará más que si utiliza cualquier otra característica de .NET Framework.
    Utiliza el Cache de datos para almacenar las coleccionas más comunes utilizadas en la aplicación Web. Esto reducirá el número de accesos a la base de datos, disminuyendo el cuello de botella que a menudo suele ocurrir con una base de datos central.
    Utiliza el elemento OutputCache de los controles y páginas que tengan más concurrencias y mayor tráfico para evitar la ejecución en el servidor sobre un control o página común que ya se haya procesado. Esto mejorará considerablemente el uso de CPU, mejorando el rendimiento global de la aplicación y el servidor tendrá más recursos disponibles para aumentar el rendimiento en las peticiones entrantes. En un futuro redactaré un post específicamente para esta funcionalidad.
    Amplía esta información sobre Caché aquí.
    Amplía esta información sobre OutputCaché aquí.

    Para entornos balanceados se recomienda utilizar funcionalidades que permitan gestionar la ubicación única de almacenamiento de caché (caché distribuida entre servidores).
    Amplía esta información sobre Caché distribuida aquí.
    Amplía esta información sobre Microsoft Velocity aquí.
    Amplía esta información sobre N-Cache aquí.
    Novedades de OutputCache para ASP.net 4.0

  • Utiliza la paginación y ordenación desde la base de datos y no sobre la interfaz de usuario (UI).
    Normalmente los controles más utilizados con soporte a la paginación es el GridView. Aunque debemos recuperar todos los datos para que el control gestione y fragmente en páginas dichos resultados.
    La recuperación de los datos y la ejecución que le conlleva al control realizar la paginación supone un coste notable que puede influir negativamente al rendimiento. Realizar la paginación sobre el origen de datos (sobre procedimientos almacenados configurados para ello), devolviendo exclusivamente los datos que se mostrarán en una determinada página sobre un conjunto total administrado por la base de datos, mejorará enormemente el rendimiento de la aplicación.
    Comentar que el control GridView utiliza muchísimos recursos del .NET debido al gran abanico de posibilidades y funcionalidades que nos permite/aporta. Esto también puede afectar negativamente al rendimiento, consumos de CPU y velocidad de carga.
    Si el conjunto de datos a mostrar no realiza ninguna funcionalidad específica o compleja debemos optar por controles con menos funcionalidades y posibilidades, pero que a su vez nos ofrezcan mejor rendimiento y más agilidad en la carga, como por ejemplo el Repeater.

  • Considera desactivar la validación de eventos
    Atributo: EnableEventValidation.
    Este atributo realiza la validación de los eventos originado desde la interfaz de usuario. Si la interfaz de usuarios no permite suplantar eventos en los controles y el control de datos (creación, modificación y eliminación) se realiza de una manera encapsulada y controlada en su aplicación web, deshabilite el atributo EnableEventValidation (indicando False) para evitar pérdida de rendimiento y evitar el coste que supone que ASP.NET realice las validaciones por ti.
    Amplía esta información aquí.

  • Deshabilita el modo de depuración
    Deshabilita siempre el modo de depuración antes de implementar una aplicación de producción o realizar cualquier medida del rendimiento. Si el modo de depuración está habilitado, el rendimiento de la aplicación puede verse afectado. Indique Debug=False en el WebConfig.
    Amplía esta información aquí.

  • Precompila la aplicación
    Una aplicación Web se compila por lotes en la primera solicitud de un recurso. Si no se ha compilado ninguna página de la aplicación, la compilación por lotes compila todas las páginas de un directorio en fragmentos para mejorar el uso del disco y de la memoria. Puede utilizar la herramienta aspnet_compiler.exe para precompilar una aplicación Web y evitar el proceso de compilación en la primera solicitud.
    Amplía esta informaciónaquí.

  • Controla el uso de las excepciones (Try/Catch)
    El tratamiento de excepciones degrada significativamente el rendimiento de la aplicación. Es aconsejable filtrar posibles excepciones mediante condiciones.

  • Implementa en código administrado los componentes COM llamados frecuentemente
    .Net Framework permite trabajar con los componentes COM tradicionales, pero usar versiones antiguas no mejora el rendimiento. En algunos casos actúa de manera desfavorable al rendimiento de la aplicación. Cada caso es particular por lo que la mejor manera de decidir si transformar un componente es verificar las numero de llamadas a las funciones del código administrado desde el código no administrado. Es recomendable transformar en código administrado todos los componentes COM que requieran un gran numero de llamadas para interactuar.

Amplía esta información aquí.

4 thoughts on “Optimizando el rendimiento de ASP .net

  1. Hola José, primero que nada felicitarte por tu trabajo el cual me parece muy interesante, sobre todo porque son pocos los sitios donde se dan el tiempo de enseñar estas cosas que al final resultan vitales para el rendimiento en una aplicación web… mi inquietud va mas porque antes yo programaba en jsp y había la opción de poner varios formularios(ejemplo 2) en una misma pagina html eso lo hacia porque me dijeron que asi sólo enviaba la información de los controles html que se encontraban dentro de un form en particular ahora que empiezo a programar en asp.net (web forms) me doy cuenta que solo puedo poner un único form y mi duda es si eso es óptimo, ya que si tengo un solo form con muchos controles y hago por ejemplo una búsqueda que solo involucra interactuar con unos cuantos controles estaría enviando información de todos los controles, entonces quisiera saber que solución hay sobre eso o que es lo que estoy malinterpretando, de antemano muchas gracias por tu respuesta…

  2. Buenas Nelmar.

    A la hora de añadir un formulario en tu página web deberás indicar si éste, quieres que se ejecute o no en el servidor (runat=”server”) para tener acceso a él desde el CodeBehind.

    Efectivamente: Una página sólo puede tener una etiqueta Form de servidor visible.

    Dado que los controles Form individuales se consideran unidades de interacción independientes, ASP.NET nunca combina varios formularios en una sola pantalla, aunque haya espacio suficiente para ello.
    Aunque si podrás incluirlos en páginas/pantallas independientes.

    Quien te hizo la recomendación estaba en lo cierto: Si reduces el número de controles anidados en el Form de servidor principal, minimizarás la ejecución, reducirás el envío de datos (incluido el tedioso ViewState) y mejorarás el rendimiento.

    Recuerda que todo el estado de los controles se almacena en el ViewState. Con lo que si deseas un buen rendimiento deberás minimizarlo o eliminarlo, en la medida de lo posible. Mantener el estado mediante programación, únicamente de controles que tú desees, no es nada complejo, además es lo más óptimo.

    Aunque todo esto, no significa que no podamos incluir formularios que no requieran ejecutarse en el servidor (sin runat=”server”). De modo que podemos incluirlo donde deseemos y controlar en todo momento el cómo, qué y cuando se envía (con ayuda de JavaScript). Y olvidándonos del ViewState.

    Realmente lo más óptimo es evitar la ejecución de ASP.NET (no añadiendo controles de servidor). Aunque perderíamos gran parte de los beneficios de ASP.NET. Se trata de encontrar un equilibrio, beneficiándote de ambos (rendimiento y funcionalidades ASP.NET).

    Si quieres más información te recomiendo estos links:

    http://msdn.microsoft.com/es-es/library/z786fs21(v=vs.90).aspx
    http://msdn.microsoft.com/en-us/magazine/cc163736.aspx#S3

    Un saludo.

  3. Primero que todo te queria agradecer por lo que haz publicado, ya que es de gran ayuda.
    Pero tengo una pregunta para hacerte, como o en que evento puedo controlar que se accedio a una imagen que tengo en el servidor, te explico, mando un correo con una imagen que va a buscarla a mi servidor, como puedo controlar que accedieron a esa imagen, es para saber quienes han leido mi correo, desde ya muchas gracias.

  4. Hola Pauls,

    Entiendo tu intención.
    Puedes crear un handler ASHX que devuelva una imagen determinada. Dicho handler, antes de servir la imagen, puede registrar los accesos e informarlos utilizando la clase Request de HttpContext. De modo que sabrás cualquier tipo de acceso a la imagen.

    Espero que pueda serte útil.

    Un saludo.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *