UNA EMPRESA DE WEB HOSTING, TODAS LAS TECNOLOGÍAS: HTML5, CSS3, .NET, C#, VB, PHP 5/7, RAZOR, JS, JSON, AJAX, ASP, WEB SERVICES, SQL SERVER, MYSQL, SQLITE, REWRITE, ...

Argentina-Hosting.Com
 

 Recursos | Artículos Propios | 10 tips + 1 plus para optimización de aplicaciones ASP

optimización de aplicaciones ASPLa demora entre el click de un usuario impaciente y el resultado devuelto en la pantalla de su navegador pueden hacer que el usuario se vaya del sitio. Si su sitio es comercial, esto puede causar la pérdida de una venta.

No podemos tener control sobre la velocidad de la conexión del usuario, pero ciertamente podemos intentar optimizar nuestros sitios ASP para obtener el mejor rendimiento posible.

Ante todo, y este podría llamarse acertadamente el tip #0, utilice la extensión .asp en las páginas que al menos contengan una línea de contenido dinámico. Sino, serán páginas HTML convencionales y ahorrará muchos recursos simplemente cambiándoles la extensión a ".htm" o ".html".

Luego de esta aclaración inicial, las siguientes pautas, al ser utilizadas metódicamente en sus desarrollos web, contribuirán a la optimización de sus aplicaciones y harán que se ejecuten más rápida y eficientemente en el entorno ASP.

Aquí vamos...

(1) Utilizar la directiva Option Explicit

Option ExplicitUtilice la directiva Option Explicit en todas sus páginas ASP. Esta directiva debe colocarse al tope de las páginas ASP, pero debajo de la directiva @. Por ejemplo:

 

<% @ Language = VBScript %>
<%
Option Explicit

'otros códigos ASP

%>

 

La función de Option Explicit es forzar al programador a declarar todas las variables que utilizará. Por ejemplo:

 

<% @ Language = VBScript %>
<%
Option Explicit

Dim Variable_1, Variable_2
'otros códigos ASP

%>

 

Muchos desarrolladores consideran que esto es útil para la depuración de las aplicaciones, ya que evita la posibilidad de cometer un error de tipeo en el nombre de una variable e inadvertidamente crear nuevas variables (por ejemplo, Cadnea=... en lugar de Cadena=...).

Pero quizás lo más importante es que las variables declaradas son más rápidas que las no declaradas. El motor de ASP referencia las variables no declaradas por nombre, mientras que las variables declaradas tienen asignado un valor ordinal. De esta manera, las variables declaradas son referenciadas por este ordinal y así accedidas más rápidamente.

 

(2) Deshabilitar el estado de sesiones

estado de sesionesPuede incrementar notablemente la velocidad de ejecución de sus aplicaciones deshabilitando el estado de sesiones desde la primera línea de toda página ASP que no utilice ningún objeto Session. Esto afecta sólo a la página en la que se indica explícitamente que no se van a utilizar sesiones y se logra colocando la siguiente declaración en la primera línea de la página ASP:

 

<% @ EnableSessionState = False %>

 

Esta línea debe ser la primera de la página ASP, sino recibirá un error similar a "El comando @ sólo puede usarse una vez en la página Active Server.".

Para efectuar más de una declaración @, como definir además el lenguaje del script, debería colocar todas las directivas en la misma línea (la primera línea de la página), así:

 

<% @ Language = VBScript EnableSessionState = False %>

 

La directiva EnableSessionState le indica al servidor que no inicie una nueva sesión cada vez que esta página ASP es llamada. Esto no quiere decir que no podrá mantener sesiones en las páginas que lo necesiten. En tales páginas no coloque esta declaración o indique explícitamente:

 

<% @ EnableSessionState = True %>

 

que es el valor tomado por defecto cuando no se utiliza la declaración EnableSessionState.

Otra de las razones para utilizar esta directiva es que las sesiones provocan un interesante problema con los marcos (frames). ASP garantiza que sólo un requerimiento de sesión será ejecutado en un determinado momento. Esto asegura que si un navegador requiere múltiples páginas a la vez para un mismo usuario, sólo un requerimiento ASP afectará la sesión a la vez, evitando problemas de multiprocesamiento al acceder al objeto Session.

Desafortunadamente, las páginas de un mismo conjunto de marcos (frameset) serán tratadas en forma serializada, una después de otra, en lugar de ser procesadas simultáneamente. Así, el usuario deberá esperar más tiempo debido a que cada página ASP de cada marco será procesada de a una. Como moraleja de la situación planteada, si ciertas páginas de un frameset no se ven afectadas por variables de sesión, asegúrese de indicarle esto a ASP a través de la declaración @EnableSessionState = False en tales páginas.

Nota: Si deshabilita el estado de sesiones y necesita asignar el "Locale ID" (LCID) para una página, puede hacerlo de la siguiente manera (el LCID indicado corresponde a Español-Argentina):

 

<% @ Language = VBScript EnableSessionState = False LCID = 11274 %>

 

 

(3) Habilitar Response.Buffer

Response.BufferOtra factor que mejorará el rendimiento de su aplicación web es asignar el valor true a la propiedad Response.Buffer. Esto acelera la ejecución debido a que no se envía ninguna respuesta al navegador cliente hasta que la página sea ejecutada completamente. Así, la respuesta es transferida de una sola vez en lugar de en pequeñas partes durante el proceso de ejecución.

Para habilitar el buffer en la respuesta de la página ASP debe agregar la línea Response.Buffer = True debajo de la directiva Option Explicit:

 

<% @ Language = VBSscript EnableSessionState = False %>
<%
Option Explicit
Response.Buffer = True

'otros códigos ASP

%>

 

TCP/IP funciona mucho más eficientemente cuando se envían unos pocos bloques de mayor tamaño en lugar de muchos bloques pequeños.

Una queja común al utilizar el buffer en la respuesta es que los usuarios perciben que las páginas ASP parecen más lentas (aún cuando el tiempo completo de procesamiento es mucho menor). Esto se debe a que los usuarios deben esperar a que la página entera sea generada antes de comenzar a ver algo.

Para páginas que requieren un considerable tiempo de procesamiento puede deshabilitar el buffer en la respuesta colocando Response.Buffer = False. Sin embargo, una mejor estrategia es utilizar el método Response.Flush. Este método envía al navegador todo el HTML que ha sido generado hasta un determinado momento. Por ejemplo, después de generar 100 líneas de una tabla de 1000 líneas, puede llamar a Response.Flush para forzar el envío de las 100 líneas al navegador. Esto permite que el usuario vea las primeras 100 líneas mientras se van procesando las 100 subsiguientes.

(notar que en el ejemplo anterior de una tabla de 1000 líneas, muchos navegadores no comenzarán a mostrar la tabla hasta que reciban la etiqueta de cierre </table>; para solucionar esto intente separar la tabla en múltiples tablas con menos filas y llame a Response.Flush después de que cada tabla ha sido generada completamente. De todos modos las últimas versiones de los navegadores comienzan a mostrar las tablas antes de que sean completamente descargadas, y lo hacen más rápidamente si especifica el ancho de las columnas de las tablas).

Otro reclamo común al habilitar el buffer en la respuesta es que este buffer puede utilizar una gran cantidad de memoria del servidor al generar páginas muy grandes. Más allá de la prudencia en no trabajar con páginas demasiado grandes, este problema puede ser corregido utilizando criteriosamente Response.Flush.

 

(4) Utilizar el objeto Session de forma prudente

objeto sessionEs recomendable evitar el uso de variables de sesión. Las sesiones producen múltiples problemas cuando son utilizadas en sitios web muy concurridos.

A menos que se explicite el no uso de sesiones a través de @EnableSessionState=False, ASP crea automáticamente una sesión por cada usuario que accesa una página ASP de una aplicación web. Cada sesión por sí sola toma unos 10 KB de memoria. La sesión permanece "viva" hasta que se cumple el período de TimeOut, que por defecto es de 20 minutos pero cuyo valor puede cambiarse a través de la siguiente directiva:

 

<% Session.TimeOut = xx %>

 

donde xx es un número entero que representa el período de TimeOut para la sesión en minutos.

Como una alternativa al uso del objeto Session, hay otras opciones para mantener el estado de las sesiones en una aplicación web. Usualmente se recomiendan cookies, variables QueryString pasadas a través de las URL's y variables ocultas (hidden) pasadas desde los formularios.

En el caso que no pueda evitar el uso del objeto Session, al menos asegúrese de NO colocar grandes cantidades de datos en este objeto. Colocar un objeto de ADO u otro objeto COM en un objeto Session será muy probablemente una causa de dolores de cabeza en el futuro cuando múltiples usuarios accedan la aplicación.

 

(5) Definir explícitamente las colecciones al utilizar el objeto Request

Para recuperar las variables enviadas desde formularios o a través de URL's, a veces utilizamos códigos como el siguiente:

 

<%
Dim Nombre
Nombre = Request("nombre")
%>

 

El objeto Request tiene cinco colecciones más una colección por defecto. Una llamada a la colección por defecto es la que se observa en el código anterior. Las otras colecciones son: Form, QueryString, ClientCertificates, ServerVariables y Cookies.

Todos estamos familiarizados con estas colecciones, ya que permiten ganar acceso a la información enviada desde el cliente.

Cuando se realiza una llamada a la colección Request por defecto, se busca en cada una de las subcolecciones en el siguiente orden:

  1. QueryString
  2. Form
  3. Cookies
  4. ClientCertificates
  5. ServerVariables

El proceso se detiene cuando se encuentra la primera coincidencia. Si se está pasando una gran cantidad de información entre páginas, el uso de la colección por defecto puede resultar en retardos (especialmente si se está tratando de recuperar la colección ServerVariables).

Siempre que sea posible defina explícitamente la colección desde la que desea traer un valor. Por ejemplo, para el caso de una variable llamada "nombre" que proviene de un post realizado desde un formulario, la codificación correcta sería:

 

<%
Dim Nombre
Nombre = Request.Form("nombre")
%>

 

 

(6) Uso del archivo GLOBAL.ASA

GLOBAL.ASA es un archivo OPCIONAL que puede contener declaraciones de objetos, variables y métodos que pueden ser accedidos desde cualquier página de una aplicación ASP. Este archivo debe estar alojado en la carpeta raíz de la aplicación ASP y cada aplicación sólo puede tener un archivo GLOBAL.ASA.

Desde el GLOBAL.ASA puede indicarle a los objetos Application y Session qué hacer cuando la aplicación/sesión comienza y qué hacer cuando la aplicación/sesión termina.

Recomendaciones:

  • Si desconoce la funcionalidad de este archivo o no necesita utilizarlo, NO lo suba al sitio web. Cada usuario que acceda a una página ASP disparará los eventos definidos en el archivo GLOBAL.ASA.
  • No deje los métodos Session_OnStart o Session_OnEnd vacíos. Aunque no haya código en el cuerpo de estos métodos, igual son interpretados. El hecho que existan significa tiempo consumido tratando de invocarlos.

Por ejemplo, un archivo GLOBAL.ASA que no necesite hacer uso de los eventos Session_OnStart y Session_OnEnd debería verse similar a:

 

<Script Language="VBscript" runat="server">

Sub Application_OnStart
'código
End Sub

Sub Application_OnEnd
'código
End Sub

</Script>

 

Si desea ver la estructura completa de un archivo GLOBAL.ASA estándar y conocer más acerca de su funcionalidad, puede visitar el siguiente artículo: El archivo GLOBAL.ASA

 

(7) Evitar redimensionar las matrices

Trate de evitar redimensionar las matrices. En cuanto al rendimiento refiere, es mucho mejor asignar el tamaño inicial de una matriz al "peor de los casos" o a un tamaño considerado medio y redimensionar sólo en caso de ser necesario. Esto no significa que destine un par de megabytes de memoria a la matriz si sabe que no va a necesitarlos.

El código siguiente muestra el mal uso de Dim y ReDim:

 

<%
Dim Mi_Matriz()
Redim Mi_Matriz(2)
Mi_Matriz(0) = "Auto"
Mi_Matriz(1) = "Camión"
Mi_Matriz(2) = "Motocicleta"
'...
' otros códigos después de los cuales se da cuenta que necesita más
' espacio, entonces ...
Redim Preserve Mi_Matriz(4)
Mi_Matriz(3) = "Bicicleta"
Mi_Matriz(4) = "Triciclo"
%>

 

Es mucho mejor simplemente dimensionar la matriz al tamaño correcto inicialmente (en este caso a 4), que redimensionarla para hacerla más grande. Puede ocupar un poco más de memoria (si no termina utilizando todos los elementos), pero ganará en velocidad.

 

(8) Evitar la concatenación de cadenas dentro de bucles

Muchos programadores van construyendo una cadena de texto mientras recorren un bucle, como en el siguiente ejemplo:

 

Cadena = "<table>" & vbCrLf
For Each Campo in RS.Fields
    Cadena = Cadena & "<th>" & Campo.Name & "</th> "
Next

While Not RS.EOF
    Cadena = Cadena & vbCrLf & "<tr>"
    For Each Campo in RS.Fields
        Cadena = Cadena & "<td>" & Campo.Value & "</td> "
    Next
    Cadena = Cadena & "</tr>"
    RS.MoveNext
WEnd

Cadena = Cadena & vbCrLf & "</table>"
Response.Write (Cadena)

 

Este código afecta seriamente el rendimiento de la aplicación. Concatenar una cadena repetidamente toma un tiempo de procesamiento cuadrático; el tiempo que toma ejecutar este bucle es proporcional al cuadrado del número de registros multiplicado por el número de campos.

Un ejemplo más simple quizás aclare la situación:

 

Cadena = ""
For i = Asc("A") to Asc("Z")
    Cadena = Cadena & Chr(i)
Next

 

En la primera iteración se obtiene una cadena de un caracter (A). En la segunda iteración, VBScript tiene que redimensionar la cadena y copiar dos caracteres (AB). Y así sucesivamente...

En la iteración final N (26 para este ejemplo), VBScript tuvo que redimensionar y copiar N caracteres dentro de la variable "Cadena". Esto hace un total de 1+2+3+...+N que es lo mismo que N*(N+1)/2 copias.

En el ejemplo anterior del recordset, si había 100 registros de 5 campos cada uno, el bucle principal hubiese sido ejecutado 100*5 = 500 veces y el tiempo tomado para efectuar las copias y redimensionamientos sería proporcional a 500*500 = 250.000. Este es un número inmenso para un recordset de tamaño moderado.

En estos ejemplos el código podría ser mejorado reemplazando la concatenación de la cadena por Response.Write(), escribiendo directamente los datos en el cliente en lugar de almacenarlos en una cadena. Si Response.Buffer está asignado al valor "true" (como debería estarlo siempre), sería más rápido aún debido a que Response.Write() agregaría los datos al buffer del objeto Response.

Así, una manera mucho más eficiente de escribir el código del primer ejemplo sería:

 

Response.Write ("<table>" & vbCrLf)
For Each Campo in RS.Fields
    Response.Write ("<th>" & Campo.Name & "</th> ")
Next

While Not RS.EOF
    Response.Write (vbCrLf & "<tr>")
    For Each Campo in RS.Fields
        Response.Write( "<td>" & Campo.Value & "</td> ")
    Next
    Response.Write ("</tr>")
    RS.MoveNext
WEnd

Response.Write (vbCrLf & "</table>")

 

 

(9) Comparar variables de un mismo tipo y utilizar variables locales

¡Compare manzanas con manzanas! En lugar de hacer que el motor ASP implícitamente busque los tipos de datos, fórcelo a que realice la comparación de la manera que usted necesita. Esto hará que las comparaciones ocurran de la manera que espera y se realicen más eficientemente.

Por ejemplo, en lugar de escribir:

 

If CLng(RS("lo_que_sea")) = 1 OR CLng(RS("lo_que_sea")) = 3 Then

 

almacene la variable localmente. Por un lado para evitar múltiples operaciones de conversión de tipos de datos y por otro para evitar leer el valor desde el recordset múltiples veces. Un código más eficiente sería:

 

lo_que_sea = CLng(RS("lo_que_sea"))
If lo_que_sea = 1 OR lo_que_sea = 3 Then

 

 

(10) Evitar el uso de Server.MapPath

El método MapPath del objeto Server mapea una ruta relativa o virtual a una ruta física en el disco del servidor.

No utilice Server.MapPath a menos que sea realmente necesario. Esto provoca otro requerimiento que el servidor debe procesar. Utilice los paths físicos directamente cuando desarrolle su sitio web para incrementar la performance. Si no conoce la ruta física a un archivo en el servidor de su proveedor de web hosting, ejecute el método Server.MapPath para saberlo. Por ejemplo, suba un script ASP en su sitio web con el siguiente código:

 

<% Response.Write (Server.MapPath("/")) %>

 

Al llamar este script desde un navegador podrá ver la ruta física de la carpeta raíz de su sitio web en el disco del servidor.

 

PLUS: Medidor de Tiempo de Ejecución

A continuación se ofrece un script ASP que tiene la función de medir el tiempo (en milisegundos) que le toma a ASP procesar una determinada secuencia de código. Este script le será de utilidad para medir en su equipo de desarrollo cómo afectan al tiempo de ejecución los distintos consejos dados y otras prácticas de programación que desee ensayar.

Como generalmente las rutinas de prueba son sencillas (unas pocas líneas de código), usualmente devuelven tiempos tan pequeños que son mostrados como cero por el script de medición. Para obtener una mejor idea de cómo afecta una optimización en el código sobre el rendimiento, en algunas ocasiones es recomendable colocar el código a probar en un bucle para que se ejecute múltiples veces.

Por ejemplo, en el script suministrado se desea probar cuánto tiempo le toma al servidor crear y destruir un objeto recordset. Como el tiempo para realizar esta tarea para un solo recordset es muy prequeño, se realiza el mismo procceso de creacion/destrucción del objeto 10.000 veces. Entonces, el tiempo indicado por el Medidor de Tiempo de Ejecución corresponderá a la creación/destrucción de 10.000 recordsets (unos 200 milisegundos en una PC AMD Athlon XP funcionando a 2 GHz con 512 MB de RAM y con sistema operativo Windows XP / IIS 5.1).

Para utilizar el Medidor de Tiempo de Ejecución de scripts ASP con sus propios códigos de prueba, reemplace las líneas:

 

Dim RS, i
For i = 1 to 10000
    Set RS = Server.CreateObject("ADODB.Recordset")
    Set RS = Nothing
Next

 

por los códigos cuyo tiempo de ejecución desea medir.

IMPORTANTE: Utilice este script de prueba en su equipo de desarrollo. No lo pruebe en el servidor de producción de su proveedor de web hosting. Algunas rutinas de prueba podrían consumir demasiados recursos o incluso salirse de control si tienen fallas en la codificación. En su PC de prueba a lo sumo deberá hacer un reinicio, pero en un servidor de producción puede afectar el rendimiento de todos los sitios web alojados en el mismo y hasta hacerlo caer.

Copie el siguiente código y péguelo en un archivo que puede llamar test.asp:

 

<% @ Language = VBScript EnableSessionState = False %>
<%
'===========================================================
'Argentina-Hosting.Com --> http://www.argentina-hosting.com
'===========================================================
Option Explicit
Response.Buffer = True
'===========================================================
'Codigo para evitar el cacheo
Response.Buffer = True
Response.Expires = -1000
Response.ExpiresAbsolute = Now() - 1
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "no-cache"
'===========================================================
%>
<HTML>
<HEAD><TITLE>
MONITOR DE TIEMPO DE EJECUCION - Argentina-Hosting.Com
</TITLE></HEAD>
<BODY>

<%
Dim Comienzo, Fin
Comienzo = Timer()
%>

<%
'===========================================================
' Aquí comienza el código cuyo tiempo de ejecución se desea medir

Dim RS, i
For i = 1 to 10000
    Set RS = Server.CreateObject("ADODB.Recordset")
    Set RS = Nothing
Next

' Aquí termina el código cuyo tiempo de ejecución se desea medir
'===========================================================
%>

<%
Fin = Timer()
Response.Write("<b>Tiempo de Ejecución: " & 1000*(Fin - Comienzo) & " [miliSeg]</b>")
%>
</BODY></HTML>

 

 

©Argentina-Hosting.Com
https://argentina-hosting.com

Microsoft Windows 2012
 

PLAN GOLD

  • Espacio Web: 500 MB
  • Espacio Mail: 500 MB
  • Transferencia: 15 GB
  • Cuentas de Correo: 50
  • Abono: AR$ 230/mes
  • Setup: $0
  • .NET 1.1, 2.0, 3.5 y 4.6
  • ASP, PHP, ...
  • Más detalles

PLAN PLATINUM

  • Espacio Web: 1500 MB
  • Espacio Mail: 1000 MB
  • Transferencia: 35 GB
  • Cuentas de Correo: 150
  • Abono: AR$ 330/mes
  • Setup: $0
  • .NET 1.1, 2.0, 3.5 y 4.6
  • ASP, PHP, ...
  • Más detalles

Aloje 10 sitios web por $330/mes !! Detalles

Planes Contratar Consultas FAQs Argentina Recursos Términos y Condiciones

[ Argentina-Hosting.Com - Web Hosting de Alta Performance ]

Recursos para Webmasters Respuestas a Preguntas Frecuentes Contratar Servicios Acceso al Panel del Cliente Háganos llegar sus consultas Planes y Precios Registro de Dominios Optimización y Alta en Buscadores Desarrollo de Aplicaciones Web