Está en la página 1de 25

FormatDate(now(),vbgeneraldate) 26/07/2001 14:23:48

FormatDate(now(),vblongdate) jueves, 26 de julio de 2001


FormatDate(now(),vbshortdate) 26/07/2001
FormatDate(now(),vblongtime) 14:23:48
FormatDate(now(),vbshorttime) 14:23

No olvidar poner como primera línea de la página 


<% @LCID = 1034 %>
si queremos las fechas en castellano

por ejemplo

<% OPTION EXPLICIT %>

<%mivariable=122%>

'esto daria error

asp2.asp

<% OPTION EXPLICIT %>

<%dim mivariable
mivariable=122%>

'esto NO daria error

.-Mediante un formulario y capturando la información con request.form

asp1.asp

<form method="POST" action="asp2.asp">


<p><input type="text" name="mivariable" size="20"></p>
<p><input type="submit" value="Enviar" name="Enviar"></p>
</form>

asp2.asp

<%
mivariable=request.form("mivariable")
%>

2.- Mediante una cadena de consulta a modo de link y capturando la información con
request.querystring

asp1.asp
<a href="asp2.asp?mivariable=hola">Paso de variables</a>

asp2.asp

<%
mivariable=request.querystring("mivariable")
%>

DE QUE PAGINA VIENEN MIS VISITAS ? 

<%
urldelavisita=request.servervariables("HTTP_REFERER")
%>

Este articulo ha sido leído 10,637 veces

Conservar los saltos de linea

Cuando recibimos textos desde un texarea de un formulario, para almacenarlo en una BD, nos encontramos con el
problema de que al mostrar luego este texto en una página HTML no se respetan los altos de línea introducidos
originalmente.
Para evitar esto, lo que podemos hacer es sustituir estos saltos de linea por caracteres "<br>" antes de introducirlos en la
base de datos mediante la funcion Replace
 
<%comentarios=replace(request.form("comentarios"),chr(10),"<br>")%>
 
 

Redireccionar una página con un Timer


Puedes redireccionar una pagina pasado un tiempo con las etiquetas META
Ejemplo:
 
<head>
<meta http-equiv="refresh" content="15;URL=http://www.ibm.com">
<title>Página redirecionada a IBM a los 15 segundos</title>
</head>
 
 
Este articulo ha sido leído 16,559 veces
Redireccion de vuelta después de un login
Pregunta y respuesta extraída de los Foros de AspTutor
Pregunta:
me gustaría que alguien me dijera como redireccionar un navegador hacia donde venia, ejemplo, un usuario no
tiene logging, lo mando a la pagina del login y luego lo redirecciono a donde estaba con su loggin de alta!!!
Respuesta dada por Luisdop
Lo primero que debes hacer, es saber en todo momento donde te encuentras, así sabes donde tienes que volver
(se podría usar javascript y volver con history.go(-1) pero la página no se refrescaría)... para eso puedes usar la
variable de servidor PATH_INDEX, como lo mejor es un ejemplo, aquí tienes uno:

1º En la página donde haces la comprobación del login de usuario, imaginate que la comprobación es ver si la
variable "acceso_permitido" tiene el valor True y que la página del login se llama login.asp y está en el directorio
raiz de la web. En la página escribiriamos (antes de la etiqueta <head>)
<%
Path_index=Request.ServerVariables("PATH_INFO")
If acceso_permitido<>True Then Response.redirect("/login.asp?Origen=" & Path_index)
%>

2. En la página del login escribiremos:

Origen=Request.Querystring("Origen")
'....
'Comprobamos los datos
'....
'Y si la contraseña es correcta (Login_ok=true)lo redireccionamos de vuelta a casa
If Login_ok=True Then
Response.redirect(Origen)
else
Response.redirect(/acceso_denegado.htm)
end if

La Función Split
Descripción

Devuelve una matriz unidimensional, basada en cero, que contiene un


número especificado de subcadenas.

Sintaxis

Split(expresión[, delimitador[, cuenta[, comparación]]])

La sintaxis de la función Split tiene las siguientes partes:

Parte Descripción
expresión Requerido. Expresión de cadena que contiene las subcadenas y
delimitadores. Si expresión es una cadena de longitud cero, Split
devuelve una matriz vacía, es decir, una matriz sin elementos ni datos.

delimitador Opcional. Carácter de cadena que se usa para identificar los límites de
las subcadenas. Si se omite, se asume que el carácter delimitador es el
carácter de espacio (" "). Si delimitador es una cadena de longitud
cero, se devuelve una matriz de un solo elemento que contiene toda la
expresión.

cuenta Opcional. número de subcadenas que se va a devolver; -1 indica que se


devuelven todas las subcadenas.

comparación Opcional. Valor numérico que indica el tipo de comparación que se va


a usar al evaluar las subcadenas. Consulte la sección Valores para
saber cuáles son los valores permitidos.

Valores

El argumento comparación puede tener los siguientes valores:

Constante Valor Descripción

vbBinaryCompare 0 Realiza una comparación binaria.

vbTextCompare 1 Realiza una comparación de texto.

Comentarios

El siguiente ejemplo usa la función Split para devolver una matriz a


partir de una cadena. La función realiza una comparación de texto del
delimitador y devuelve todas las subcadenas.

Dim MiCadena, MiMatriz


MiCadena = Split("ASPTUTOR es GRANDE!", -1, 1)
' MiCadena(0) contiene "ASPTUTOR".
' MiCadena(1) contiene "es".
' MiCadena(2) contiene "GRANDE!".

 
Este articulo ha sido leído 12,047 veces

La función Ubound

Descripción

Devuelve el mayor subíndice disponible para la dimensión indicada de una matriz.


Sintaxis

UBound(nombredematriz[, dimensión])

La sintaxis de la función UBound tiene las siguientes partes:

Parte Descripción

nombredematriz Requerido. nombre de la variable de matriz que cumple con el estándar de asignación de nombres de
variables.

dimensión Opcional. Número entero que indica para qué dimensión se va a devolver el límite superior. Use 1 para la
primera dimensión, 2 para la segunda y así sucesivamente. Si se omite dimensión, se asume que es igual a
1.

Comentarios

La función UBound se usa con la función LBound para determinar el tamaño de una matriz. Use la
función LBound para buscar el límite inferior de una dimensión de una matriz.

El límite inferior de cualquier dimensión siempre es igual a 0. Como resultado, UBound devuelve los
siguientes valores para una matriz con estas dimensiones:

Dim A(100,3,4)
Instrucción Valor devuelto

UBound(A, 1) 100

UBound(A, 2) 3

UBound(A, 3) 4

Este articulo ha sido leído 12,512 veces

Formatos de fecha y hora (Función FormatDateTime)


Descripción

Devuelve una expresión con formato de fecha u hora.

Sintaxis

FormatDateTime(Fecha[, FormatoConNombre])

La sintaxis de la función FormatDateTime tiene las siguientes partes:


 

Parte Descripción

Fecha Requerido. Expresión de fecha a la que se va a aplicar el formato.

FormatoConNombre Opcional. Valor numérico que indica el formato de fecha y hora usado. Si se omite, se usa vbGeneralDate.

Valores

El argumento FormatoConNombre tiene los siguientes valores:

Constante Valor Descripción

vbGeneralDate 0 Muestra una fecha o una hora. Si hay una parte que sea fecha, la muestra con formato de fecha
corta. Si hay una parte que sea hora, la muestra con formato de hora largo. Si está presente, se
muestran ambas partes.

vbLongDate 1 Muestra una fecha con el formato de fecha larga especificado en la configuración regional del
equipo.

vbShortDate 2 Muestra una fecha con el formato de fecha corta especificado en la configuración regional del
equipo.

vbLongTime 3 Muestra una hora con el formato de hora especificado en la configuración regional del equipo.

vbShortTime 4 Muestra una hora con el formato de 24 horas (hh:mm).

El siguiente ejemplo usa la función FormatDateTime para dar formato de fecha larga a la expresión y asignarla a MiFechaHora:

Function ObtenerFechaActual
' FormatDateTime da formato a Date como fecha larga.
ObtenerFechaActual = FormatDateTime(Date, 1)
End Function

Como vaciar un array

No existe ninguna sentecia en Vbscrip para vaciar un array, pero podemos hacerlo
usando usando las sentencias Redim y Ubound
 

ReDim miArray(UBound(miArray))
 
Esta sentencia reinicializa el array miArray

 
Este articulo ha sido leído 28,408 veces
Sugerencias sobre ASP para la mejora del rendimiento y el estilo (I)

Len Cardinal, Consultor senior, Microsoft Consulting Services


George V. Reilly, Responsable de rendimiento de Microsoft IIS
Adaptación de un artículo (en inglés) de Nancy Cluts
Ingeniero de tecnología de desarrolladores
Microsoft Corporation
Resumen: este artículo presenta una serie de sugerencias para la optimización 
de las aplicaciones ASP y VBScript.
Contenido
Introducción
Sugerencia 1: Almacenar en caché datos utilizados frecuentemente en el servidor Web
Sugerencia 2: Almacenar en caché datos utilizados frecuentemente en el objeto de aplicación o de sesión
Sugerencia 3: Almacenar en caché datos y HTML en los discos del servidor Web
Sugerencia 4: Evitar almacenar en caché componentes no ágiles en los objetos de aplicación o de sesión
Sugerencia 5: No almacenar en caché conexiones de la base de datos en los objetos de aplicación o de sesión
Sugerencia 6: Utilizar prudentemente el objeto de sesión
Sugerencia 7: Encapsular el código en los objetos COM
Sugerencia 8: Adquirir los recursos en el último momento y liberarlos cuanto antes
Sugerencia 9: La ejecución fuera de proceso permite el equilibrio entre el rendimiento y la confiabilidad
Sugerencia 10: Utilizar Option Explicit
Sugerencia 11: Utilizar variables locales en las subrutinas y las funciones
Sugerencia 12: Copiar datos utilizados frecuentemente en las variables de la secuencia
Sugerencia 13: Evitar redimensionar las matrices
Sugerencia 14: Utilizar el búfer de respuesta

Introducción
El rendimiento es una característica fundamental y, de hecho, si una aplicación no se diseña desde un principio teniéndolo en cuenta, más
adelante será preciso volver a desarrollarla. Dicho de esta manera uno se pregunta: ¿existe alguna estrategia eficaz para maximizar el rendimiento
de la aplicación ASP (Páginas Active Server)?
Este artículo proporciona una serie de sugerencias que permiten optimizar las aplicaciones ASP y Visual Basic® Scripting Edition (VBScript) y
en él se discuten las muchas trampas y dificultades a las que se ha tenido que hacer frente. Las sugerencias que se enumeran se han utilizado en
distintos sitios, incluyendo el de Microsoft, http://www.microsoft.com, y se ha comprobado que funcionan a la perfección. Este artículo da por
sentado que el lector conoce los aspectos básicos del desarrollo de ASP, incluidos VBScript y/o JScript, las aplicaciones y sesiones ASP y el
resto de objetos intrínsecos ASP (Request, Response y Server).
A menudo el rendimiento de ASP depende de mucho más que el propio código ASP. En lugar de cubrir todo el tema en un solo artículo, se han
enumerado al final del mismo los recursos relacionados con el rendimiento. Estos vínculos tratan sobre temas relacionados o no con ASP, por
ejemplo, Objetos de datos ActiveX® (ADO), Modelo de objetos componentes (COM), bases de datos y la configuración de Internet Information
Server (IIS). Se trata de algunos de nuestros vínculos preferidos y recomendamos que los visite.

Sugerencia 1: Almacenar en caché datos utilizados frecuentemente en el servidor Web


Una página ASP típica recupera los datos desde el almacenamiento central de datos y, a continuación, convierte los resultados en lenguaje de
marcado de hipertexto (HTML). Independientemente de la velocidad de la base de datos, recuperar los datos desde la memoria resulta un proceso
mucho más rápido que recuperarlos desde dicho almacenamiento central de datos. La lectura de los datos en un disco local también se lleva a
cabo más rápidamente que si se recuperan desde la base de datos. Por otra parte, también se puede incrementar el rendimiento almacenando los
datos en caché en el servidor Web, ya sea en la memoria o en el disco.
El almacenamiento en caché constituye un mecanismo clásico que permite el equilibrio entre el espacio y el tiempo. Si se almacenan los
elementos adecuados, se puede observar un impresionante aumento en el rendimiento. Para que la caché resulte efectiva ésta debe almacenar los
datos que se vuelven a utilizar con relativa frecuencia y aquellos que pueden resultar (moderadamente) costosos de actualizar. Contar con datos
obsoletos en la caché supone malgastar la memoria.
Los datos que no cambian con excesiva frecuencia son los candidatos idóneos para que se almacenen en caché, ya que uno no debe preocuparse
por la sincronización con la base de datos después de un tiempo; listas de cuadros combinados, tablas de referencia, recortes DHTML, cadenas
de lenguaje de marcado extensible (XML), elementos de menú y variables de configuración de los sitios (incluyendo nombres de origen de datos
(DSN), direcciones de protocolo de Internet (IP) y rutas Web). Sin embargo, es necesario señalar que lo que se almacena en caché es la
presentación de los datos y no los datos en sí. Si una página ASP no se modifica con demasiada frecuencia y resulta costoso almacenarla en
caché (por ejemplo, un catálogo completo de productos), se debe considerar la posibilidad de generar previamente el HTML, en lugar de volver a
escribirlo para cada solicitud.
¿Dónde deben almacenarse los datos y cuáles son las principales estrategias para el almacenamiento en caché? Por regla general los datos se
almacenan, bien en la memoria, bien en los discos del servidor Web. Las dos sugerencias que se proporcionan a continuación cubren ambas
opciones.

Sugerencia 2: Almacenar en caché datos utilizados frecuentemente en el objeto de aplicación o de


sesión
Los objetos Application y Session ASP resultan unos contenedores adecuados para el almacenamiento de los datos, que se pueden asignar tanto
al objeto Application como a Session y que permanecen en la memoria entre solicitudes HTTP. Los datos de la sesión se almacenan por usuario,
mientras que los de la aplicación los comparten todos los usuarios.
¿En qué punto suele cargar los datos en la aplicación o la sesión? Con frecuencia los datos se cargan durante el inicio de la sesión o de la
aplicación, para lo que es necesario agregar el código adecuado a Application_OnStart() o Session_OnStart()respectivamente. Estas funciones
deben encontrarse en Global.asa, aunque si no es así, siempre se podrán agregar. Los datos también se pueden cargar cuando se los necesita por
vez primera. Para ello, agregue el código (o escriba una función de secuencia reutilizable) a la página ASP de forma que compruebe la existencia
de los datos y los cargue, si fuera necesario. Este ejemplo ilustra la técnica clásica de mejora del rendimiento conocida como evaluación
perezosa, es decir, no se calcula nada hasta que no se sabe que se necesita. Un ejemplo:
<%
Function GetEmploymentStatusList
Dim d
d = Application("EmploymentStatusList")
If d = "" Then
' La función FetchEmploymentStatusList (no se muestra)
' busca los datos en la BD y devuelve una matriz
d = FetchEmploymentStatusList()
Application("EmploymentStatusList") = d
End If
GetEmploymentStatusList = d
End Function
%>
Se podrían emplear funciones similares con cada grupo de datos necesario.
¿En qué formato deben almacenarse los datos? Se puede almacenar cualquier tipo Variant, ya que se trata de variables de secuencia. Por ejemplo,
se pueden almacenar cadenas, enteros o matrices. A menudo se almacenará el contenido de un recordset ADO en uno de estos tipos de variables.
Para extraer los datos del recordset ADO, se pueden copiar manualmente en las variables VBScript, un campo por vez. Resulta más rápido y
sencillo utilizar una de las persistentes funciones del recordset ADO GetRows(),GetString() (en inglés) o Save() (ADO 2.5) (en inglés). No es el
objetivo de este artículo proporcionar todos los detalles sobre este tema, sin embargo, sí que se ofrece un ejemplo ilustrativo sobre cómo utilizar
GetRows() para devolver una matriz de datos del recordset:
' Obtener Recordset, devolver como matriz
Function FetchEmploymentStatusList
Dim rs
Set rs = CreateObject("ADODB.Recordset")
rs.Open "seleccionar StatusName, StatusID en EmployeeStatus", _
"dsn=employees;uid=sa;pwd=;"
FetchEmploymentStatusList = rs.GetRows() " Devolver datos como matriz
rs.Close
Set rs = Nothing
End Function
Un refinamiento aún mayor sería almacenar en caché el HTML de la lista en lugar de la matriz. Aquí se muestra un sencillo ejemplo de cómo
hacerlo:
' Obtener Recordset, devolver como lista de opción HTML
Function FetchEmploymentStatusList
Dim rs, fldName, s
Set rs = CreateObject("ADODB.Recordset")
rs.Open "seleccionar StatusName, StatusID en EmployeeStatus", _
"dsn=employees;uid=sa;pwd=;"
s = "<seleccionar nombre=""EmploymentStatus">" & vbCrLf
Set fldName = rs.Fields("StatusName") ' Enlace de campos ADO
Do Until rs.EOF
' La siguiente línea viola Evitar la concatenación de las cadenas...,
' pero no importa ya que estamos creando una caché
s = s & " <option>" & fldName & "</option>" & vbCrLf
rs.MoveNext
Loop
s = s & "</select>" & vbCrLf
rs.Close
Set rs = Nothing ' Consultar Adquirir los recursos en el último...
FetchEmploymentStatusList = s ' Devolver datos como cadena
End Function
En las condiciones adecuadas se pueden almacenar en caché los propios recordsets ADO en el ámbito de aplicación o de sesión, con la salvedad
de dos casos:
 ADO debe marcarse como de subprocesamiento libre.
 Se debe utilizar un recordset desconectado.

Si no se puede garantizar que se van a cumplir dichos requisitos, los recordsets ADO no se deben almacenar en caché. En la sugerencias Evitar
almacenar en caché componentes no ágiles... y No almacenar en caché conexiones... que aparecen a continuación se discuten los principales
riesgos que supone el almacenamiento de objetos COM en el ámbito de aplicación o de sesión.
En esta circunstancia, los datos permanecen allí hasta que el desarrollador decide modificarlos con la programación, hasta que termina la sesión o
hasta que se reinicia la aplicación Web. ¿Qué ocurre si es necesario actualizar los datos? Para forzar manualmente una actualización de los datos
de la aplicación, se puede llamar a una página ASP a la que sólo tenga acceso el administrador para que actualice los datos. Otra alternativa es
actualizarlos automáticamente de forma periódica utilizando una función. El ejemplo siguiente almacena una marca de tiempo con los datos y los
actualiza después de un intervalo de tiempo concreto.
<%
' error no mostrado...
Const UPDATE_INTERVAL = 300 ' Actualizar intervalo, en segundos

' Función para devolver lista de estado


Function GetEmploymentStatusList
UpdateEmploymentStatus
GetEmploymentStatusList = Application("EmploymentStatusList")
End Function

' Actualizar periódicamente los datos en caché


Sub UpdateEmploymentStatusList
Dim d, strLastUpdate
strLastUpdate = Application("LastUpdate")
If (strLastUpdate = "") Or _
(UPDATE_INTERVAL < DateDiff("s", strLastUpdate, Now)) Then

' Nota: se pueden obtener dos o más llamadas. Es suficiente y simplemente


' resultará en varias búsquedas innecesarias (existe una solución)

' La función FetchEmploymentStatusList (no se muestra)


' busca los datos en la BD y devuelve una matriz
d = FetchEmploymentStatusList()

' Actualizar el objeto de aplicación. Utilizar Application.Lock()


' para garantizar la coherencia de los datos
Application.Lock
Application("EmploymentStatusList") = d
Application("LastUpdate") = CStr(Now)
Application.Unlock
End If
End Sub
Para ver otro ejemplo consulte World’s Fastest ListBox with Application Data (en inglés).
Es necesario advertir que almacenar en caché matrices de gran tamaño en los objetos Session o Application no es muy recomendable. Antes de
poder tener acceso a cualquiera de los elementos de la matriz, la semántica de los lenguajes de secuencias requiere que se realice una copia
temporal de la matriz completa. Por ejemplo, si se almacena en caché una matriz de cadenas de 100.000 elementos que asigne códigos postales
norteamericanos a estaciones meteorológicas locales en el objeto Application, ASP debe copiar primero las 100.000 estaciones meteorológicas
antes de que se pueda extraer una sola cadena. En este caso, resultaría mucho mejor elaborar un componente personalizado con un método
también personalizado que permitiera almacenar las estaciones, o bien, utilizar uno de los componentes de diccionario.
Un comentario adicional en la misma línea de no tirar las frutas frescas con las pochas: las matrices proporcionan un mecanismo rápido para la
consulta y el almacenamiento de datos clave que son contiguos en la memoria. La indización de un diccionario constituye un proceso más lento
que la de una matriz. Se debe seleccionar la estructura de datos que ofrezca el mejor rendimiento en cada caso.

Sugerencia 3: Almacenar en caché datos y HTML en los discos del servidor Web
Puede que en ocasiones el volumen de datos que se deben almacenar en la memoria caché sea demasiado elevado. No obstante, el término
“demasiado” constituye una apreciación, ya que depende de la cantidad de memoria que se desea utilizar, así como del número de elementos que
se quieren almacenar en caché y la frecuencia en la que dichos elementos se recuperan. En cualquier caso, si son demasiados los datos que se
deben guardar, tenga en cuenta que siempre podrá almacenarlos en archivos XML o de texto en los discos duros de los servidores Web. Puede
combinar el almacenamiento en discos y en memoria para crear una óptima estrategia de almacenamiento en caché para su sitio.
Hay que tener en cuenta que cuando se está analizando el rendimiento de una única página ASP, la recuperación de los datos del disco puede que
no resulte una operación más rápida que su recuperación desde la base de datos. Sin embargo, el almacenamiento en caché reduce la carga que
deben soportar la base de datos y la red. En condiciones de cargas mayores se mejorará considerablemente el rendimiento general. El
almacenamiento en caché puede ser muy útil cuando se desean almacenar los resultados de una consulta costosa, como es el caso de las tablas
múltiples, de procedimientos almacenados más complejos o de grandes conjuntos de resultados. Pero, como siempre, se deben comparar otros
esquemas.
ASP y COM proporcionan algunas herramientas que permiten construir esquemas de almacenamiento basados en discos. Las funciones Save() y
Open() del recordset ADO guardan y cargan los recordsets desde el disco. Se pueden utilizar ambos métodos para volver a escribir el código de
muestra de la anterior sugerencia, Almacenar en caché datos utilizados frecuentemente en el objeto de aplicación..., sustituyendo Save() por el
código que desarrolla el objeto Application.
Existen otros componentes que funcionan con archivos:
 Scripting.FileSystemObject (en inglés), que permite crear, leer y escribir archivos.
 MSXML, el analizador de Microsoft® XML que se incluye con Internet Explorer, que admite el almacenamiento y la carga de
documentos XML.
 El objeto LookupTable (ejemplo, utilizado en MSN) supone una elección más que acertada para la carga de listas simples desde el
disco.

Por último, otra alternativa posible es el almacenamiento en caché de la presentación de los datos en un disco en lugar de los propios datos. El
HTML procesado previamente puede almacenarse en disco como un archivo de extensión .htm o .asp, archivos a los que los hipervínculos
pueden conducir directamente. Se puede automatizar el proceso de generación de HTML utilizando algunas de las herramientas del mercado
como XBuilder (en inglés) o las características para la publicación en Internet de Microsoft® SQL Server™. Otra opción es #incluir
miniprogramas de HTML en un archivo .asp. También se pueden leer los archivos HTML desde el disco utilizando FileSystemObject, o bien,
emplear XML para el procesamiento previo (en inglés).

Sugerencia 4: Evitar almacenar en caché componentes no ágiles en los objetos de aplicación o de


sesión
Mientras que el almacenamiento en caché de los datos en el objeto Application o Session puede ser una excelente idea, el mismo tipo de
almacenamiento de objetos COM puede suponer ciertas dificultades. Puede resultar tentador guardar objetos COM utilizados frecuentemente en
los objetos Application o Session. Desafortunadamente, muchos de estos objetos COM, incluyendo aquellos desarrollados en Visual Basic 6.0 o
posterior, pueden ocasionar serios cuellos de botella cuando se almacenan en los objetos Application o Session.
Más específicamente, cualquier componente que no sea ágil (en inglés) puede producir cuellos de botella en los objetos Session o Application.
Un componente ágil es un componente marcado como ThreadingModel=Both que agrega el ordenamiento de subprocesamiento libre (FTM) o un
componente marcado como ThreadingModel=Neutral. (El modelo Neutral es una novedad en Windows® 2000 y COM+). Los siguientes
componentes no son ágiles:
 Componentes de subprocesamiento libre (a menos que agreguen el FTM).
 Componentes de subprocesamiento controlado.
 Componentes de subprocesamiento único.

Los componentes configurados (Microsoft Transaction Server (MTS)/biblioteca COM+ y aplicaciones/paquetes del servidor) no son ágiles a
menos que se consideren Neutral. Los componentes de subprocesamiento controlado, entre otros componentes no ágiles, ofrecen mejores
resultados en el ámbito de página (es decir, se crean y se destruyen en una sola página ASP).
En IIS 4.0, un componente marcado como ThreadingModel=Both se consideraba ágil. Esto ya no es suficiente en IIS 5.0. El componente no sólo
debe marcarse como Ambos, sino que debe agregar el FTM. El artículo sobre agilidad (en inglés) describe cómo hacer que los componentes de
C++ escritos con la biblioteca de plantillas activa (ATL) agreguen el FTM. Tenga en cuenta que si el componente almacena en caché los
punteros de la interfaz, también dichos punteros deben ser ágiles o deben almacenarse en la tabla de interfaz global COM (GIT). Si no se puede
volver a compilar un componente marcado como Ambos para agregar el FTM, se podrá marcar dicho componente como
ThreadingModel=Neutral. De forma alternativa, si no desea que IIS realice la comprobación de la agilidad (es decir, desea que los componentes
no ágiles se almacenen en el ámbito de aplicación o de sesión), puede establecer AspTrackThreadingModel como True en la metabase. Cambiar
AspTrackThreadingModel no es una operación muy recomendable.
IIS 5.0 enviará un mensaje de error si se intenta almacenar un componente no ágil creado con Server.CreateObject en el objeto Application. Se
puede solucionar el problema utilizando <object runat=server scope=application ...> en Global.asa, aunque no es recomendable, ya que conduce
al ordenamiento y serialización, como se explica a continuación.
¿Qué es lo que ocurre si se almacenan en caché componentes no ágiles? Un componente de este tipo almacenado en el objeto Session
“bloqueará” la sesión a un subproceso de trabajo ASP. ASP mantiene un conjunto de procesos de trabajo que se ocupan de las solicitudes.
Normalmente el primer subproceso de trabajo que estuviera libre se ocuparía de la nueva solicitud. Si se bloquea una sesión a un subproceso, la
solicitud debe esperar hasta que el subproceso asociado se encuentre disponible. A continuación presentamos una analogía que bien puede servir
para explicarlo: uno va al supermercado, selecciona varios tipos de artículos comestibles y abona el importe en la caja nº 3. Imagine que a partir
de ese momento, siempre que compre artículos en ese supermercado, debe abonarlos en la misma caja nº 3, aunque haya menos personas
esperando en otras cajas o algunas de ellas se encuentre vacía.
El almacenamiento de componentes no ágiles en el ámbito de aplicación tiene un efecto aún peor sobre el rendimiento. ASP debe crear un
subproceso espacial para ejecutarlos, lo que tiene dos consecuencias: todas las llamadas deben realizarse en serie y se deben ordenar en dicho
subproceso. El ordenamiento supone que los parámetros deben almacenarse en un área compartida de memoria; se realiza un costoso cambio de
contexto en el subproceso especial; se ejecuta el método del componente; se ordenan los resultados en el área compartida; y un cambio adicional
de contexto devuelve el control al subproceso original. La serialización implica que los métodos se ejecutan de uno en uno. No se puede dar la
circunstancia de que dos subprocesos de trabajo ASP ejecuten simultáneamente métodos en el componente compartido, ya que esto acabaría con
la concurrencia, especialmente en equipos con varios procesadores. Y aún peor, todos los componentes no ágiles en el ámbito de aplicación
comparten un subproceso (“Host STA”), de forma que los efectos de la serialización son aún más marcados.
¿Resulta demasiado confuso? Aquí tiene algunas reglas generales. Si está desarrollando objetos en Visual Basic (6.0) o posterior, no debe
almacenarlos en caché en los objetos Application o Session. Si desconoce el modelo de subprocesamiento de un objeto, es mejor que no lo
almacene. En lugar de almacenar objetos no ágiles debe crearlos y liberarlos en cada página. Los objetos se ejecutarán directamente en el
subproceso de trabajo, con lo que no se producirán ni la serialización ni la ordenación. El rendimiento será el adecuado si los objetos COM se
ejecutan en un cuadro de IIS y si no tardan demasiado en iniciarse y destruirse. Tenga en cuenta que los objetos de subprocesamiento único no
deben utilizarse de este modo. Preste atención: ¡VB puede crear objetos de subprocesamiento único! Si debe utilizar objetos de subprocesamiento
único de esta manera (como una hoja de cálculo de Microsoft Excel), no espere un buen rendimiento.
Los recordsets ADO pueden almacenarse en caché de forma segura cuando ADO se marca como de subprocesamiento libre. Para marcar ADO
como de subprocesamiento libre, utilice el archivo Makfre15.bat, que se ubica normalmente en el directorio \\Archivos de programa\Archivos
comunes\System\ADO.
Advertencia: ADO no debe marcarse como de subprocesamiento libre si no se utiliza Microsoft Access como base de datos. El recordset ADO
siempre debe estar desconectado. Por regla general, si no se puede controlar la configuración de ADO del sitio (por ejemplo, el caso de los
fabricantes independientes de software [ISV], que distribuyen aplicaciones Web a los clientes y éstos de ocupan de sus propias configuraciones),
probablemente sea mejor que no almacene en caché los recordsets.
Los componentes de diccionario también se incluyen en la categoría de objetos ágiles. El objeto LookupTable carga sus datos desde el archivo de
datos y resulta muy útil para los datos de cuadros combinados y como información de configuración. PageCache de Duwamish Books (en
inglés) proporciona la semántica del diccionario, al igual que el diccionario Caprock. Estos objetos, o derivados, pueden formar la base de una
eficaz estrategia de almacenamiento. Tenga en cuenta que el objeto Scripting.Dictionary NO es ágil y que no debe almacenarse en el ámbito de
aplicación o de sesión.

Sugerencia 5: No almacenar en caché conexiones de la base de datos en los objetos de aplicación o de


sesión
Almacenar en caché conexiones ADO no es por lo general una buena estrategia. Si un objeto Connection se almacena en el objeto Application y
se utiliza en todas las páginas, éstas competirán por utilizar la conexión. Si el objeto Connection se almacena en el objeto Session ASP, se creará
una conexión a la base de datos para cada usuario. Con esto se pierden los beneficios que suponía la agrupación de conexiones y se incrementa
en exceso la carga tanto en el servidor Web como en la base de datos.
En lugar de almacenar las conexiones a la base de datos, una alternativa mejor es crear y destruir los objetos ADO en cada una de las páginas
ASP que los utilizan. Se trata de un mecanismo muy eficaz ya que IIS incorpora la agrupación de conexiones. De forma más precisa, IIS habilita
automáticamente la agrupación de conexiones de OLEDB y ODBC. Así se garantiza que la creación y posterior destrucción de las conexiones de
cada página ofrece resultados positivos.
Dado que los recordsets almacenan una referencia a la conexión a la base de datos, no se deben almacenar en caché en el objeto Application o
Session. No obstante, sí que se pueden almacenar en caché de forma segura los recordsets desconectados, ya que estos últimos no guardan
referencia alguna a la conexión de datos. Para desconectar un recordset, siga los dos pasos siguientes:
Set rs = Server.CreateObject("ADODB.RecordSet")
rs.CursorLocation = adUseClient ' paso 1

' Poblar el recordset con datos


rs.Open strQuery, strProv

' desconectar el recordset del proveedor de datos y el origen de datos


rs.ActiveConnection = Nothing ' paso 2
Puede obtener más información sobre la agrupación de conexiones en las referencias a ADO y SQL Server.

Sugerencia 6: Utilizar prudentemente el objeto de sesión


Después de haber roto una lanza en favor de las virtudes del almacenamiento en caché en las aplicaciones y en las sesiones, vamos a sugerir
evitar el objeto Session. Las sesiones pueden suponer ciertas dificultades cuando se utilizan en sitios con mucha actividad, como veremos más
adelante. Por sitios con mucha actividad generalmente entendemos aquellos que solicitan cientos de páginas por segundo o los que visitan
simultáneamente miles de usuarios. Esta sugerencia nos parece aún más importante en el caso de los sitios que se deben escalar horizontalmente,
es decir, aquellos que utilizan varios servidores para acomodar la carga o para implementar la tolerancia a los errores. En sitios más pequeños,
como los de una intranet, las ventajas que proporcionan las sesiones bien compensan los inconvenientes.
Recapitulemos: ASP crea automáticamente una sesión para cada usuario que realiza la solicitud al servidor Web. Cada sesión dispone de casi 10
KB de memoria extra (siempre por encima de la cantidad de datos almacenados en la sesión) y ralentiza un poco todo el proceso. La sesión
permanece viva durante un período de tiempo de espera configurable, que generalmente es de 20 minutos.
El principal problema que plantean las sesiones no es el rendimiento, sino la escalabilidad. Las sesiones no se extienden a los servidores Web;
una vez se ha creado una sesión en un servidor, sus datos permanecen allí. Esto significa que si se utilizan las sesiones en una granja Web, se
debe diseñar una estrategia para las solicitudes de cada usuario de forma que siempre se dirijan al servidor en el que existe la sesión del usuario.
Esto se denomina “pegar” un usuario al servidor Web. El término “sesiones pegadas” deriva de él. Si se produjera algún error en el servidor
Web, se perdería el estado de la sesión de los usuarios que se han “pegado”, ya que las sesiones no se almacenan en el disco.
Las estrategias de implementación de este tipo de sesiones incluyen soluciones de hardware y software como el equilibrio de carga para redes (en
inglés) en Windows 2000 Advanced Server y Local Director de Cisco, que pueden implementarlas, a expensas de cierta escalabilidad. Estas
soluciones no son perfectas. Confirmar una solución de software propia en este punto no es muy recomendable (solíamos utilizar filtros ISAPI, la
eliminación de URL, etc.).
El objeto Application tampoco se extiende a los servidores; si es necesario compartir y actualizar los datos de la aplicación por la granja Web,
será preciso utilizar la base de datos central. No obstante, se debe señalar que los datos de una aplicación de sólo lectura aún son de utilidad en
las granjas Web.
Casi con toda seguridad, en sitios de misión crítica se deseará distribuir al menos dos servidores Web, aunque simplemente sea por incrementar
el tiempo de actividad (mantenimiento del servidor y control de errores). Por otra parte, para diseñar una aplicación de misión crítica se deben
implementar las “sesiones pegadas” o simplemente evitar las sesiones de cualquier tipo, así como cualquier otra técnica de control del estado que
almacene a los usuarios en servidores Web por separado.
Si no desea utilizar sesiones, asegúrese de desactivarlas. Esta operación se puede realizar, en el caso de la aplicación, con el Administrador de
servicios de Internet (consultar la documentación de ISM). Si, por el contrario, decide utilizar sesiones, siempre puede minimizar su impacto en
el rendimiento de varias formas distintas.
Puede mover el contenido que no requiera sesiones (por ejemplo, pantallas de ayuda, áreas de visitantes, etc.) a otra aplicación ASP en la que se
hayan desactivado las sesiones. Utilizando el esquema de página a página, se sugiere a ASP que el objeto de sesión no es necesario en una página
concreta; utilice la directiva siguiente situada en la parte superior de la página ASP:
<% @EnableSessionState=False %>
Una buena razón por la que conviene utilizar esta directiva es que las sesiones crean un interesante problema con los conjuntos de marcos. ASP
garantiza que sólo se ejecutará una solicitud de la sesión por vez. De esta manera, si el explorador solicita varias páginas para un sólo usuario, la
sesión sólo se ocupará de una solicitud ASP; con ello se evitan los problemas ocasionados por el subprocesamiento múltiple cuando se tiene
acceso al objeto Session. Desafortunadamente, se obtiene como resultado que todas las páginas de un conjunto de marcos aparecen en serie, una
tras otra, en lugar de hacerlo simultáneamente. Puede que el usuario se vea obligado a esperar algún tiempo hasta que aparezcan todos los
marcos. La moraleja de esta pequeña historia es la siguiente: si ciertas páginas de conjuntos de marcos no dependen de la sesión, es necesario
informar de ello a ASP utilizando la directiva @EnableSessionState=False.
Como alternativa a la utilización del objeto Session existen varias opciones que permiten controlar el estado de la sesión. Con tamaños reducidos
(menos de 4 KB), generalmente recomendamos que se utilicen las cookies, las variables QueryString y las de formulario oculto. Cuando se trata
de tamaños de datos mayores como los de un carro de la compra, la elección más adecuada es una base de datos central. El tema de las técnicas
de control de estado en las granjas Web ha generado mucha literatura; se pueden consultar algunas referencias en la sección relativa al estado de
la sesión.

Sugerencia 7: Encapsular el código en los objetos COM


Si se dispone de mucho VBScript o JScript, siempre se puede mejorar el rendimiento moviendo el código a un objeto COM compilado. El código
compilado generalmente se ejecuta con mayor rapidez que el interpretado. Los objetos COM compilados pueden tener acceso a otros objetos
COM gracias a un “enlace en tiempo de compilación”, un método más eficaz para invocar métodos de objetos COM que el de “enlace en tiempo
de ejecución” que emplea la secuencia.
Existen más ventajas (además de la mejora del rendimiento) al encapsular el código en objetos COM:
 Los objetos COM permiten separar la lógica de presentación de la lógica empresarial.
 Los objetos COM permiten reutilizar el código.
 Muchos desarrolladores encuentran que el código escrito en VB, C++ o Visual J++ es mucho más sencillo de depurar que ASP.

Los objetos COM también tienen sus inconvenientes, incluyendo el tiempo de desarrollo inicial y la necesidad de nuevas habilidades de
programación. Encapsular pequeñas cantidades de ASP puede ir en detrimento del rendimiento en lugar de mejorarlo. Esto ocurre normalmente
cuando una pequeña cantidad de código ASP se incluye en el objeto COM. En este caso, la carga que supone crear e invocar el objeto COM
supera a las ventajas de utilizar código compilado. Se trata de una cuestión de ensayo y error el determinar qué combinación de secuencia ASP y
código de objetos COM genera el mejor resultado en cuanto a rendimiento. Microsoft ha mejorado enormemente el rendimiento de las
secuencias y de ADO en Windows 2000/IIS 5.0 en comparación con Windows NT® 4.0/IIS 4.0. De esta forma, la ventaja del rendimiento que se
disfrutaba al utilizar el código compilado sobre el código ASP se ha reducido con la introducción de IIS 5.0.
Para conocer algunos interesantes debates sobre las ventajas e inconvenientes de utilizar objetos COM en ASP, consulte Guía del componente
ASP y Programming Distributed Applications with COM and Microsoft Visual Basic 6.0 (en inglés). Si desea distribuir los componentes COM,
es importante que realice una prueba de carga (en inglés) de los mismos. De hecho, se deberían realizar por norma pruebas de este tipo en todas
las aplicaciones ASP.

Sugerencia 8: Adquirir los recursos en el último momento y liberarlos cuanto antes


Se trata de una pequeña sugerencia. En general, es mejor adquirir los recursos tarde y liberarlos pronto. Esto se refiere tanto a objetos COM
como a los controladores de archivos y demás recursos.
Las conexiones y recordsets ADO son los candidatos idóneos para esta optimización. Cuando haya terminado de utilizar un recordset, por
ejemplo, tras crear una tabla con sus datos, se debe liberar inmediatamente, en lugar de esperar hasta el final de la página. Establecer la variable
de VBScript como Nothing es la mejor opción. No permita que el recordset se quede fuera de ámbito. Libere, además, todos los objetos
Command o Connection relacionados. (No olvide llamar a Close() en los recordsets o conexiones antes de establecerlos como = Nothing). De
esta manera se reduce el intervalo de tiempo durante el cual la base de datos debe hacer juegos malabares con los recursos y se libera la conexión
de la base de datos a la agrupación de conexiones tan pronto como es posible.

Sugerencia 9: La ejecución fuera de proceso permite el equilibrio entre el rendimiento y la


confiabilidad
Tanto ASP como MTS/COM+ presentan una serie de opciones de configuración que permiten compensar la confiabilidad y el rendimiento. Es
preciso entender dichas compensaciones cuando se está construyendo y distribuyendo una aplicación.

Opciones de ASP

Las aplicaciones ASP pueden configurarse de forma que se ejecuten de tres formas distintas. Con IIS 5.0, el “nivel de aislamiento” de la
terminología se ha introducido para describir dichas opciones. Los tres valores del nivel de aislamiento son bajo, medio y alto:
 Aislamiento bajo. Se admite en todas las versiones de IIS y se trata del método más rápido. Ejecuta ASP en Inetinfo.exe, el proceso
primario de IIS. Si se produjera un error en la aplicación ASP, éste se trasladaría a IIS. (Para reiniciar IIS en la versión 4.0, los
Webmasters deberían supervisar el sitio empleando herramientas como InetMon y lanzar archivos por lotes para reiniciar el servidor en
caso de error. IIS 5.0 introduce el proceso de reinicio confiable (en inglés), que permite reiniciar automáticamente un servidor en el que
se ha producido un error).
 Aislamiento medio. IIS 5.0 introduce este nuevo nivel, que se denomina como fuera de proceso, ya que ASP se ejecuta fuera de
proceso de IIS. En el aislamiento medio, todas las aplicaciones ASP configuradas para ejecutarse como medias comparten un único
espacio de proceso. Esto reduce el número de procesos que son necesarios que ejecutar varias aplicaciones ASP fuera de proceso en un
cuadro. Medio corresponde al nivel de aislamiento predeterminado en IIS 5.0.
 Aislamiento alto. Admitido en IIS 4.0 e IIS 5.0, el aislamiento alto también está fuera de proceso. Si se produjera un error en ASP, el
servidor Web no se vería afectado. La aplicación ASP se reiniciaría automáticamente en la siguiente solicitud ASP. Con el aislamiento
alto, cada aplicación ASP configurada para ejecutarse como alta lo hace en su propio espacio de proceso. De esta forma se protegen las
aplicaciones ASP unas de otras. El principal problema que presenta este sistema es que requiere un proceso independiente para cada
aplicación ASP. También puede suponer un incremento en la carga que se debe soportar cuando se deben albergar docenas de
aplicaciones en un cuadro.

Entonces, ¿cuál es la opción más adecuada? En IIS 4.0 se podía observar un declive en el rendimiento cuando la aplicación se ejecutaba fuera de
proceso. Se ha trabajado a conciencia en este tema en IIS 5.0 y se ha logrado minimizar el coste de la ejecución de las aplicaciones ASP fuera de
proceso. De hecho, en la mayoría de las comprobaciones, las aplicaciones ASP fuera de proceso en IIS 5.0 se ejecutan más rápidamente que las
aplicaciones en proceso en IIS 4.0. No obstante, las aplicaciones en proceso generan (con un nivel de aislamiento bajo) el mejor rendimiento en
ambas plataformas. A pesar de esta circunstancia, resulta difícil obtener beneficios del nivel bajo si la frecuencia de aciertos o la salida máxima
son relativamente bajas. Por tanto, es mejor no alcanzar el nivel de aislamiento bajo hasta que se necesiten cientos o miles de páginas por
segundo y por servidor Web. Como siempre, se deben comprobar las distintas configuraciones para determinar las compensaciones se que desean
obtener.
Nota: cuando se ejecutan aplicaciones ASP fuera de proceso (con aislamiento medio o alto), se ejecutan en MTS en NT4 y en COM+ en
Windows 2000. Es decir, en NT4 se ejecutan desde Mtx.exe y, en Windows 2000, por su parte, lo hacen en DllHost.exe. Se pueden ver los
procesos en el Administrador de tareas. También se pueden conocer los detalles de la configuración de los paquetes MTS o de las aplicaciones
COM+ por parte de IIS para aplicaciones ASP fuera de proceso.

Opciones de COM

Los componentes COM también presentan tres opciones de configuración que, sin embargo, no son completamente análogas a las de ASP. Los
componentes COM pueden estar: “no configurados”, configurados como aplicaciones de biblioteca o configurados como aplicaciones de
servidor. No configurado significa que el componente no se ha registrado con COM+ y que se ejecutará en el espacio de proceso de quien realizó
la llamada, es decir, se encuentran “en proceso”. Las aplicaciones de biblioteca también se encuentran en proceso, sin embargo se benefician de
los servicios de COM+, incluyendo la seguridad, las transacciones y el soporte del contexto. Las aplicaciones de servidor se configuran para
ejecutarse en su propio espacio de proceso.
Puede que vea unos beneficios importantes en el uso de componentes no configurados comparados con las aplicaciones de biblioteca, lo que sí
está claro es que verá unos beneficios mucho mayores en cuanto al rendimiento si utiliza estas últimas en lugar de las aplicaciones de servidor.
Esto se debe a que las aplicaciones de biblioteca se ejecutan en el mismo proceso que ASP, mientras que las del servidor lo hacen en su propio
espacio de proceso. Las llamadas de inter-proceso resultan mucho más costosas que las llamadas en proceso. Asimismo, cuando se pasan datos,
por ejemplo, recordsets, entre procesos, todos ellos se deben copiar entre los dos procesos.
¡He aquí un problema! Cuando se utilizan aplicaciones de servidor COM, si se pasan objetos entre ASP y COM, es preciso asegurarse de que
dichos objetos implementan el denominado “subprocesamiento por valor” o MBV, ya que los que lo hacen se copian a sí mismos de un proceso a
otro. Esto resulta mucho mejor que la otra alternativa, que consistiría en que el objeto debe permanecer en el proceso del creador y que el resto de
los procesos llamarían repetidamente al proceso que se está creando para que utilice el objeto. Los recordsets ADO desconectados se
subprocesarán por valor; los conectados no. Scripting.Dictionary no implementa MBV y no debería pasarse entre procesos. Por último,
enviamos un mensaje a los programadores de VB: MBV NO se obtiene pasando el parámetro ByVal. El autor del componente original
implementaría MBV.

¿Qué se puede hacer?

Si tuviéramos que recomendar una configuración con una compensación razonable en cuanto a rendimiento y confiabilidad, sería la siguiente:
 En IIS 4.0, utilizar el nivel de aislamiento bajo de ASP y los paquetes de servidor de MTS.
 En IIS 5.0, utilizar el nivel de aislamiento medio de ASP y aplicaciones de biblioteca de COM+.

Estas son únicamente unas líneas generales; las empresas dedicadas a ello generalmente ejecutan ASP con un nivel de aislamiento medio o alto,
mientras que los servidores Web de un único propósito pueden ejecutarse con un aislamiento bajo. Analice las compensaciones y decida la
configuración que se ajusta en mayor medida a sus necesidades.

Sugerencia 10: Utilizar Option Explicit


Utilice Option Explicit en los archivos .asp. Situada en la parte superior del archivo .asp, esta directiva fuerza al desarrollador a declarar todas las
variables que se van a emplear. Muchos programadores consideran que es de gran utilidad para depurar las aplicaciones, ya que evita la
posibilidad de escribir incorrectamente el nombre de una variable o de crear accidentalmente otras nuevas (por ejemplo, MyXLMString=... en
lugar de MyXMLString=).
Quizás algo aún más importante, resulta que las variables declaradas son más rápidas que las no declaradas. El tiempo de ejecución de las
secuencias hace referencia por nombre a las variables no declaradas cada vez que se utilizan. A las variables declaradas, por otra parte, se asigna
un ordinal ya sea durante el tiempo de compilación o el de ejecución. Por consiguiente, el ordinal hace referencia a las variables declaradas.
Debido a que Option Explicit fuerza la declaración de las variables, garantiza que todas ellas se declaran para, de esta forma, facilitar el acceso a
las mismas.

Sugerencia 11: Utilizar variables locales en las subrutinas y las funciones


Las variables locales son aquellas que se declaran con las subrutinas y las funciones. Dentro de una subrutina o función, el acceso a una variable
local es mucho más rápido que a una global. La utilización de las variables también tiende a hacer que el código presente una mayor claridad, por
lo que se recomienda su uso siempre que sea posible.

Sugerencia 12: Copiar datos utilizados frecuentemente en las variables de la secuencia


Cuando se tiene acceso a los objetos COM en ASP, se deben copiar los datos de objetos utilizados frecuentemente en las variables de la
secuencia. De esta forma se reduce el número de llamadas a los métodos COM, que resultan relativamente costosos comparados con el acceso a
las variables de las secuencias. Obtener acceso a los objetos Collection y Dictionary reduce el número de costosas consultas que es preciso
llevar a cabo.
Por regla general, si se desea obtener acceso a datos de objetos más de una vez, éstos se deben introducir en una variable de secuencia. Los
protagonistas principales a los que va dirigida esta optimización son las variables de solicitud (Form y QueryString). Por ejemplo, puede que su
sitio pase una variable QueryString denominada UserID. Supongamos que se hace referencia a UserID una docena de veces en una página
concreta. En lugar de llamar a Request("UserID") doce veces, es mejor asignar UserID a una variable en la parte superior de la página ASP y, a
continuación, utilizar dicha variable por toda la página. De esta manera se evitarán 11 llamadas al método COM.
En la práctica, el acceso a las propiedades o métodos COM puede resultar costoso en apariencia. A continuación se proporciona un ejemplo de
código muy común (desde el punto de vista sintáctico):
Foo.bar.blah.baz = Foo.bar.blah.qaz(1)
If Foo.bar.blah.zaq = Foo.bar.blah.abc Then ' ...
Esto es lo que sucede cuando se ejecuta el código:
1. La variable Foo se resuelve como un objeto global.
2. La variable bar se resuelve como miembro de Foo, que resulta ser una llamada al método COM.
3. La variable blah se resuelve como miembro de Foo.bar. Este también resulta ser una llamada al método COM.
4. La variable qaz se resuelve como miembro de foo.bar.blah. Sí, de nuevo una llamada al método COM.
5. Invoque Foo.bar.blah.quaz(1). Otra llamada al método COM. ¿Se hace una idea?
6. Siga los pasos 1-3 otra vez para resolver baz. El sistema desconoce si la llamada a qaz ha cambiado el modelo de objeto, por lo que se
deben volver a realizar los pasos 1-3 para resolver baz.
7. Resuelva baz como miembro de Foo.bar.blah. Introduzca la propiedad.
8. Vuelva a seguir los pasos 1-3 para resolver zaq.
9. Siga de nuevo los pasos 1-3 y resuelva abc.

Como se puede ver, se trata de un sistema terriblemente ineficaz (y lento). La forma rápida de escribir el código en VBScript es:
Set myobj = Foo.bar.blah ' resolver blah UNA VEZ
Myobj.baz = myobj.qaz(1)
If Myobj.zaq = Myobj.abc Then '...
Si se utiliza VBScript 5.0 o posterior, se puede escribir utilizando la instrucción With:
With Foo.bar.blah
.baz = .qaz(1)
If .zaq = .abc Then '...
...
End With
Tenga en cuenta que esta sugerencia también se puede aplicar a la programación en VB.

Sugerencia 13: Evitar redimensionar las matrices


Se debe intentar evitar la redimensión de las matrices con Redim. Por lo que se refiere al rendimiento, si se dispone de un equipo restringido por
el tamaño de la memoria física, resulta mejor establecer la dimensión inicial de la matriz en el peor de los casos posible, o bien, establecerla en la
situación más óptima y redimensionar cuando sea necesario. Esto no significa que simplemente se deben asignar un par de megabytes de
memoria si se sabe que no se va a necesitarla.
El código que aparece a continuación muestra la utilización gratuita de Dim y Redim.
<%
Dim MyArray()
Redim MyArray(2)
MyArray(0) = "hola"
MyArray(1) = "adiós"
MyArray(2) = "hasta pronto"
...
' otro código en el que es necesario más espacio, entonces ...
Redim Preserve MyArray(5)
MyArray(3) = "más material"
MyArray(4) = "aún más material"
MyArray(5) = "todavía mucho más material"
%>
Es mucho más fácil dimensionar la matriz con Dim al tamaño correcto inicialmente (en este caso, 5), que redimensionarla con Redim para
aumentar su tamaño. Puede que se utilice algo de memoria (si al final no se utilizan todos los elementos), pero el incremento en la velocidad que
se obtiene bien compensa esta inversión.

Sugerencia 14: Utilizar el búfer de respuesta


Se puede almacenar en búfer la salida de una página completa activando la opción de “búfer de respuesta”. Se minimiza la cantidad de veces que
es necesario escribir en el explorador y se mejora el rendimiento general. Cada escritura supone una sobrecarga (tanto en IIS como en la cantidad
de datos que se envían), por tanto, cuantas menos escrituras sea preciso realizar, mejor. TCP/IP ofrece mejores resultados cuando se envían
varios bloques de datos grandes que cuando se deben enviar muchos bloques pequeños debido al inicio lento (en inglés) y al algoritmo de Nagle
(en inglés) (empleados para reducir las sobrecarga de la red).
Existen dos maneras de activar el búfer de respuesta. En primer lugar, se puede activar para toda la aplicación utilizando para ello el
Administrador de servicios de Internet. Se trata del enfoque recomendado, por lo que el búfer de respuesta se encuentra activado de forma
predeterminada en las aplicaciones ASP en IIS 4.0 y IIS 5.0. En segundo lugar, página a página; es decir, se puede activar el búfer de respuesta
introduciendo la siguiente línea de código en la parte superior de la página ASP:
<% Response.Buffer = True %>
Esta línea de código debe ejecutarse antes de que se escriba cualquier dato de repuesta en el explorador (es decir, antes de que aparezca el HTML
en la secuencia ASP y antes de que se envíe cualquier cookie con la colección Response.Cookies). En líneas generales, resulta mucho mejor
activar el búfer de respuesta en toda la aplicación, ya que así se evita la necesidad de escribir la anterior línea de código en cada página.

Response.Flush

Uno de los problemas que se plantean con el búfer de respuesta es los usuarios perciben que la respuesta que obtienen de las páginas ASP es
menor (aunque el tiempo global de respuesta se haya mejorado) ya que deben esperar a que se genere toda la página antes de poder ver algo. En
el caso de las páginas que tardan en cargarse, se puede activar el búfer de respuesta con Response.Buffer = False. Sin embargo, una estrategia
mucho más eficaz sería utilizar el método Response.Flush, que descarga todo el HTML de ASP en el explorador. Por ejemplo, después de que
aparezcan 100 filas de una tabla de 1.000, ASP puede llamar a Response.Flush para que fuerce los resultados y que éstos aparezcan en el
explorador; de esta forma el usuario puede ver las primeras 100 filas antes de que las restantes estén listas. Esta técnica puede proporcionar
además lo mejor de ambos métodos: el búfer de respuesta combinado con la presentación gradual de los datos en el explorador.
(Es importante señalar que en el ejemplo anterior de una tabla de 1.000 filas, muchos exploradores no empezarán a cargar la tabla hasta que vean
la etiqueta de cierre </table>. Compruebe los exploradores para obtener información sobre compatibilidad. Para solucionar este problema, intente
dividir la tabla en varias más pequeñas con menos filas cada una de ellas y llame a Response.Flush después de cada tabla. Las últimas versiones
de Internet Explorer mostrarán las tablas antes de descargarlas completamente y lo harán a una velocidad considerable especialmente si se
especifica la anchura de columna previamente; con esto, Internet Explorer se evita tener que calcular la anchura de la columna en función del
contenido de cada celda).
Otro de los problemas más comunes que presenta el búfer de respuesta es que puede utilizar gran parte de la memoria del servidor cuando genera
páginas muy extensas. Dejando a un lado la cuestión de si es recomendable o no generar páginas extensas, también se puede hacer frente a este
problema utilizando Response.Flush.
 
 

Este articulo ha sido leído 13,749 veces

Sugerencias sobre ASP para la mejora del rendimiento y el estilo (II)


Len Cardinal, Consultor senior, Microsoft Consulting Services
George V. Reilly, Responsable de rendimiento de Microsoft IIS
Adaptación de un artículo (en inglés) de Nancy Cluts
Ingeniero de tecnología de desarrolladores
Microsoft Corporation
 
Contenido
Sugerencia 15: Actualizar las instrucciones de secuencia en línea y Response.Write
Sugerencia 16: Utilizar Response.IsClientConnected antes de aventurarse en viajes más largos
Sugerencia 17: Crear una instancia de los objetos utilizando la etiqueta <OBJECT>
Sugerencia 18: Utilizar declaraciones TypeLib con ADO y otros componentes
Sugerencia 19: Beneficiarse de las capacidades de validación del explorador
Sugerencia 20: Evitar la concatenación de las cadenas en los bucles
Sugerencia 21: Habilitar el almacenamiento en caché en el explorador y en servidores proxy
Sugerencia 22: Utilizar Server.Transfer en lugar de Response.Redirect siempre que sea posible
Sugerencia 23: Utilizar barras diagonales en las URL de directorios
Sugerencia 24: Evitar utilizar variables del servidor
Sugerencia 25: Actualizar a los últimos y los más importantes
Sugerencia 26: Ajustar el servidor Web
Sugerencia 27: Realizar pruebas de rendimiento
Sugerencia 28: Consultar los vínculos de recursos

Sugerencia 15: Actualizar las instrucciones de secuencia en línea y Response.Write


La sintaxis de VBScript <% = expression %> crea el valor de “expression” en la salida de ASP. Si el búfer de respuesta no se activa, cada una de
estas instrucciones tiene como resultado que los datos se escriben en el explorador a través de la red en paquetes muy pequeños. Se trata de un
proceso que lleva algún tiempo. La intercalación de pequeñas cantidades de secuencias y HTML hace que se produzca un cambio entre el motor
de secuencia y el HTML, viéndose reducido el rendimiento. Por tanto, se recomienda utilizar la siguiente sugerencia: reemplazar las expresiones
en línea demasiado amontonadas con una llamada a Response.Write. Por ejemplo, en la siguiente muestra aparece sólo una escritura en el flujo
de respuesta por campo y fila y muchos cambios entre VBScript y HTML por fila:
<table>
<% For Each fld in rs.Fields %>
<th><% = fld.Name %></th>
<%
Next
While Not rs.EOF
%>
<tr>
<% For Each fld in rs.Fields %>
<td><% = fld.Value %></td>
<% Next
</tr>
<% rs.MoveNext
Wend %>
</table>
Este código más eficaz presenta una escritura en el flujo de respuesta por fila y se contiene en su totalidad en el bloque de VBScript:
<table>
<%
For each fld in rs.Fields
Response.Write ("<th>" & fld.Name & "</th>" & vbCrLf)
Next
While Not rs.EOF
Response.Write ("<tr>")
For Each fld in rs.Fields %>
Response.Write("<td>" & fld.Value & "</td>" & vbCrLf)
Next
Response.Write "</tr>"
Wend
%>
</table>
El efecto que se obtiene al seguir esta sugerencia es mucho mayor cuando se encuentra deshabilitada la opción de búfer de respuesta. Habilite el
búfer de respuesta y compruebe que la actualización de Response.Write incide positivamente en el rendimiento.
(En este ejemplo concreto, el bucle anidado que consituye el cuerpo de la tabla (While Not rs.EOF...) puede reemplazarse por una llamada
cuidadosamente elaborada a GetString (en inglés)).

Sugerencia 16: Utilizar Response.IsClientConnected antes de aventurarse en viajes más largos


Si un usuario se impaciencia ante la tardanza de la descarga de una página ASP, puede abandonarla incluso antes de que se empiece a ejecutar su
solicitud. Si hace clic en el botón Actualizar o cambia a otra página en el servidor, se dispondrá una nueva solicitud al final de la cola de
solicitudes ASP y una solicitud desconectada en mitad de la misma. Esto ocurre con relativa frecuencia cuando el servidor debe soportar una
carga elevada (cuando tiene una cola extensa de solicitudes a las que debe responder con tiempos de respuesta también bastante largos), con lo
que lo único que se consigue es empeorar la situación. No tiene sentido ejecutar una página ASP (especialmente una lenta y con mucha carga) si
el usuario ya no se encuentra conectado. Esta circunstancia se puede comprobar con la propiedad Response.IsClientConnected. Si devuelve
False, se debería llamar a Response.End y abandonar el resto de la página. De hecho, IIS 5.0 codifica esta operación: siempre que una página
ASP está a punto de ejecutar una solicitud, ésta se comprueba para ver cuanto tiempo ha permanecido en la cola. Si ha superado los 3 segundos,
ASP comprobará que el cliente aún sigue conectado y, si no fuera así, finalizaría la solicitud inmediatamente. Se puede utilizar
AspQueueConnectionTestTime en la metabase para ajustar el tiempo de espera a 3 segundos.
Si la página tarda demasiado en ejecutarse, se puede comprobar Response.IsClientConnected a intervalos. Cuando se habilita el búfer de
respuesta, resulta una buena idea ejecutar Response.Flush a intervalos para dar al usuario la impresión de que está sucediendo algo.
Nota: en IIS 4.0, Response.IsClientConnected no funcionará correctamente a menos que se utilice primero Response.Write. Si se habilita el
almacenamiento en búfer, también se deberá utilizar Response.Flush. En IIS 5.0, no es preciso emplearlo: Response.IsClientConnected funciona
correctamente. En cualquier caso, Response.IsClientConnected supone ciertos costes, por lo que sólo se debe utilizar antes de operaciones en las
que se inviertan, al menos, 500 milisegundos (un intervalo largo si lo que se intenta es mantener una salida de docenas de páginas por segundo).
Como norma, es mejor no llamarlo en cada iteración de un bucle estrecho, como cuando se crean las filas de una tabla; quizás sería mejor
realizarlo cada 20 o 50 filas de la tabla.

Sugerencia 17: Crear una instancia de los objetos utilizando la etiqueta <OBJECT>
Si precisa hacer referencia a los objetos que puede que no se utilicen en todas las rutas del código (especialmente en los objetos del ámbito de
servidor o de aplicación), puede declararlos utilizando la etiqueta <object runat=server id=objname> en Global.asa en lugar del método
Server.CreateObject. Dicho método Server.CreateObject crea el objeto inmediatamente. Si más tarde no vuelve a utilizarlo, acabará malgastando
los recursos. La etiqueta <object id=objname> declara objname, pero en realidad objname no se crea hasta que se utilizan por primera vez uno de
sus métodos o propiedades.
Se trata de otro ejemplo de evaluación perezosa.

Sugerencia 18: Utilizar declaraciones TypeLib con ADO y otros componentes


Cuando utilizan ADO, los desarrolladores incluyen con frecuencia adovbs.txt para obtener acceso a las distintas constantes de ADO. Este archivo
debe incluirse en cada página en la que se desea que se haga uso de dichas constantes y su tamaño es relativamente extenso, con lo que se agrega
una carga considerable al tamaño de secuencia y al tiempo que se invierte en la compilación de cada página ASP.
IIS 5.0 incorpora una nueva capacidad para enlazar a una biblioteca de tipos que permite hacer una referencia a la misma una vez y utilizarla en
cada página ASP. Con ello las páginas no se ven obligadas a compilar el archivo de constantes y los desarrolladores de componentes eliminan la
necesidad de crear archivos #include de VBScript para su utilización en ASP.
Para obtener acceso a TypeLib de ADO, introduzca una de las siguientes instrucciones en Global.asa.
<!-- METADATA NAME="Microsoft ActiveX Data Objects 2.5 Library"
TYPE="TypeLib" UUID="{00000205-0000-0010-8000-00AA006D2EA4}" -->
o bien,
<!-- METADATA TYPE="TypeLib"
FILE="C:\Archivos de programa\Archivos comunes\system\ado\msado15.dll" -->

Sugerencia 19: Beneficiarse de las capacidades de validación del explorador


Los exploradores más actuales admiten características avanzadas como XML, DHTML, miniaplicaciones Java y Remote Data Service (todos en
inglés). Puede beneficiarse de estas características siempre que sea posible, ya que lo que todas estas tecnologías comparten es su capacidad para
evitar los rodeos a la hora de tener acceso al servidor Web gracias a la validación del lado del cliente y al almacenamiento en caché de los datos.
Si ejecuta un explorador inteligente, éste podrá realizar la validación (por ejemplo, comprobando que una tarjeta de crédito dispone de una suma
de comprobación válida (en inglés) antes de ejecutar el comando). De nuevo, aprovéchese de esta característica siempre que sea posible. Al
recortar los rodeos entre el cliente y el servidor, se reducirá la carga del servidor Web y el tráfico de la red (aunque es probable que la primera
página que se envíe al explorador sea más extensa), así como en los recursos centrales a los que tiene acceso el servidor. Por otra parte, el usuario
no tendrá que visitar nuevas páginas de forma tan frecuente, mejorándose así su experiencia en el Web. No obstante, esto no libera al
desarrollador de la carga de tener que realizar la validación en el lado del servidor, de igual manera era necesario llevarla a cabo, ya que de este
modo se evitan circunstancias como datos incorrectos o exploradores que no ejecutan rutinas de validación en el lado del cliente.

Debido al hincapié que se ha hecho en la creación de HTML “independiente del explorador”, esta cuestión a menudo ha servido para animar al
desarrollador a no utilizar las características más comunes del explorador que pudieran incidir positivamente en el rendimiento. En aquellos sitios
en los que el alto rendimiento depende en gran medida del “alcance” del explorador, una buena estrategia es optimizar las páginas para los
exploradores más utilizados, con lo que ASP podría detectar fácilmente sus características con el componente de capacidades del explorador.
Herramientas como Microsoft FrontPage pueden ayudarle a diseñar un código que funcione con los exploradores y con las versiones de HTML
que tiene como objetivo. Consulte When is Better Worse? Weighing the Technology Trade-Offs (en inglés) para obtener información adicional.

Sugerencia 20: Evitar la concatenación de las cadenas en los bucles


Muchos desarrolladores construyen cadenas en un bucle como sigue:
s = "<table>" & vbCrLf
For Each fld in rs.Fields
s = s & " <th>" & fld.Name & "</th> "
Next

While Not rs.EOF


s = s & vbCrLf & " <tr>"
For Each fld in rs.Fields
s = s & " <td>" & fld.Value & "</td> "
Next
s = s & " </tr>"
rs.MoveNext
Wend

s = s & vbCrLf & "</table>" & vbCrLf


Response.Write s
Sin embargo, este enfoque presenta algunos problemas. El primero es que el tiempo invertido en la concatenación repetida de cadenas es
cuadrático; por decirlo de forma menos formal, el tiempo que se invierte en ejecutar el bucle es proporcional al cuadrado del número de registros
multiplicado por el número de campos. Un ejemplo más simple aclararía las cosas.
s = ""
For i = Asc("A") to Asc("Z")
s = s & Chr(i)
Next
En la primera iteración se obtiene una cadena de un único carácter, "A". En la segunda, VBScript debe asignar la cadena y copiar dos caracteres
("AB") a s. En la tercera debe volver a asignar s y copiar tres caracteres a s. En la iteración Nª (26ª), debe reasignar y copiar N caracteres a s. Esto
resulta en un total de 1+2+3+...+N que son N*(N+1)/2 copias.
En el ejemplo de recordset anterior, si hubiera 100 registros y 5 campos, el bucle más interno se ejecutaría 100*5 = 500 veces y el tiempo
invertido en todo el proceso de copia y reasignación sería proporcional a 500*500 = 250.000, valor algo elevado para un modesto recordset.
En este ejemplo, el código podría mejorarse reemplazando la concatenación de la cadena con Response.Write() o la secuencia en línea (<% =
fld.Value %>). Si se activa el búfer de respuesta (recomendado), el proceso sería más rápido, ya que Response.Write se agregaría a los datos al
final de cada búfer de respuesta. No sería necesario llevar a cabo ninguna reasignación adicional y resultaría un método muy eficaz.
En el caso concreto de la transformación de un recordset ADO en una tabla HTML, considere la posibilidad de utilizar GetRows o GetString (en
inglés).
Si se concatenan las cadenas en JScript, se recomienda que se emplee el operador +=; es decir, utilizar s += "cadena", no s = s + "cadena".

Sugerencia 21: Habilitar el almacenamiento en caché en el explorador y en servidores proxy


De forma predeterminada, ASP deshabilita el almacenamiento en caché en exploradores y servidores proxy, algo que tiene sentido ya que, por
naturaleza, una página ASP es dinámica y contiene información que se modifica con el tiempo. Si, por el contrario, la página no requiere
actualización cada vez que se visita, se debería habilitar el almacenamiento en caché en el explorador y el servidor proxy. De esta forma podrían
utilizar una copia “almacenada en caché” de una página durante un período de tiempo concreto que se puede controlar con facilidad. El
almacenamiento en caché puede aliviar en gran medida la carga que debe soportar el servidor y mejorar así la experiencia del usuario que tiene
acceso a la página.
¿Qué tipo de páginas dinámicas pueden ser candidatas para el almacenamiento en caché? Aquí se ofrecen algunos ejemplos:
 Una página dedicada a la meteorología, en la que el pronóstico del tiempo se actualiza sólo cada 5 minutos.
 Una página principal en la que se proporcionan noticias o comunicados de prensa y que se actualiza dos veces al día.
 Una página de un fondo de inversión mobiliaria en la que las estadísticas se actualizan cada pocas horas.

Tenga en cuenta que con el almacenamiento en el explorador y el servidor proxy se obtendrán menos registros en el servidor Web. Si lo que
desea es contar con un análisis detallado y preciso de todas las vistas de las páginas, por ejemplo, puede que el almacenamiento de este tipo no
proporcione los resultados deseados.
El almacenamiento en el explorador se controla por medio del encabezado HTTP “Expires”, que el servidor Web envía al explorador. ASP
proporciona dos simples mecanismos que permiten enviar este encabezado. Para que una página caduque tras un número específico de minutos
en el futuro, establezca la propiedad Response.Expires. El ejemplo siguiente indica al explorador que el contenido caducará a los 10 minutos:
<% Response.Expires = 10 %>
Establecer Response.Expires en un valor negativo o en 0 deshabilitará el almacenamiento en caché. Asegúrese de que utiliza números negativos
altos, como -1.000 (un poco más de un día), para solucionar las discrepancias entre los relojes del servidor y los exploradores. Una segunda
propiedad, Response.ExpiresAbsolute, permite establecer el intervalo de tiempo después del cual caducará el contenido:
<% Response.ExpiresAbsolute = #May 31,2001 13:30:15# %>
En lugar de utilizar el objeto Response para establecer el momento en el que caducará la página, se puede escribir una etiqueta <META> en el
código HTML, generalmente incluida en la sección <HEAD> del archivo HTML. Algunos exploradores respetarán esta directriz, pero no los
servidores proxy.
<META HTTP-EQUIV="Expires" VALUE="May 31,2001 13:30:15">
Por último, se puede indicar si el contenido es válido para que lo almacene en caché un servidor proxy, utilizando la propiedad
Response.CacheControl. Si se establece como “Public”, se habilitarán los servidores proxy, que almacenarán en caché dicho contenido.
<% Response.CacheControl = "Public" %>
De forma predeterminada, esta propiedad se establece como “Private”. Tenga en cuenta que no se debe habilitar el almacenamiento en caché en
el servidor proxy en el caso de las páginas que muestran datos específicos de un usuario, ya que el servidor proxy podría proporcionar dichas
páginas a otros.

Sugerencia 22: Utilizar Server.Transfer en lugar de Response.Redirect siempre que sea posible
Response.Redirect indica al explorador que debe solicitar otra página. Esta función se utiliza a menudo para redireccionar al usuario a una página
de registro o de error. Debido a que el redireccionamiento fuerza una nueva solicitud de página, el resultado es que el explorador debe visitar dos
veces el servidor Web y que éste debe administrar una solicitud adicional. IIS 5.0 introduce una nueva función, Server.Transfer, que transfiere la
ejecución a otra página ASP en el mismo servidor. De esta forma se evita que el explorador busque una segunda vez en el servidor Web, con el
resultado de una mejora en el rendimiento general del sistema, así como un mejor tiempo de respuesta para el usuario. Consulte New Directions
in Redirection (en inglés), donde podrá encontrar detalles sobre Server.Transfer y Server.Execute.
Asimismo recomendamos que consulte Leveraging ASP in IIS 5.0 (en inglés) para obtener la lista completa de nuevas características de IIS 5.0 y
ASP 3.0.

Sugerencia 23: Utilizar barras diagonales en las URL de directorios


Una sugerencia relacionada es la utilización de una barra diagonal al final (/) de las URL que conduzcan a los directorios. Si se omite dicha barra,
el explorador realiza una solicitud al servidor, sólo para que se le informe de que está solicitando un directorio. El explorador entonces intenta
una segunda solicitud con la barra agregada a la URL y sólo entonces responde el servidor con el documento predeterminado del directorio, o
bien, con una lista de directorios, si es que no existiera documento predeterminado y se encontrara habilitada la exploración del mismo. Agregar
la barra supone ir directamente al segundo paso. No obstante, para una mayor comodidad del usuario puede que sea interesante omitir la barra en
los nombres de pantalla.
Por ejemplo, introduzca:
<a href="http://msdn.microsoft.com/workshop/" title="MSDN Web
Workshop">http://msdn.microsoft.com/workshop</a>
Esto también se aplica a las URL que conducen a la página principal en un sitio Web: utilice lo siguiente: <a
href="http://msdn.microsoft.com/">, no <a href="http://msdn.microsoft.com">.
 
Sugerencia 24: Evitar utilizar variables del servidor
Tener acceso a las variables del servidor supone que el sitio Web debe realizar una solicitud especial al servidor y recopilar todas sus variables,
no exclusivamente la solicitada. Esto es casi lo mismo que intentar recuperar algo de una carpeta que se encuentra en un mohoso desván; es
necesario subir al desván y obtener primero la carpeta antes de poder conseguir el elemento. Algo muy similar ocurre cuando se solicita una
variable del servidor: el rendimiento se ve ligeramente afectado por la primera solicitud de variable que se hace al servidor. Las solicitudes
posteriores de variables adicionales no afectan al rendimiento.
Nunca se debe tener acceso a un objeto Request no calificado (por ejemplo, Request(“Data”)). En el caso de los elementos que no se encuentran
en Request.Cookies, Request.Form, Request.QueryString o Request.ClientCertificate, existe una llamada implícita a Request.ServerVariables. La
colección Request.ServerVariables es mucho más lenta que las demás.

Sugerencia 25: Actualizar a los últimos y los más importantes


Los componentes experimentan actualizaciones constantes y, por nuestra parte, recomendamos que el sistema se actualice con los últimos y más
importantes componentes del mercado. La mejor opción es actualizar a Windows 2000 (en inglés) (y por consiguiente, a IIS 5.0, ADO 2.5,
MSXML 2.5, Internet Explorer 5.0, VBScript 5.1 y JScript 5.1). IIS 5.0 y ADO 2.5 permiten implementar unas espectaculares mejoras en el
rendimiento en equipos con varios procesadores. Con Windows 2000, ASP se puede escalar con cuatro o más procesadores, mientras que con IIS
4.0, ASP no se escalaba bien con sólo dos procesadores. Cuanto mayor sea el uso que se haga del código de secuencias y de ADO en la
aplicación, mayores serán las ventajas en cuanto a rendimiento una vez se realice la actualización a Windows 2000.
Si aún no puede actualizar el sistema a Windows 2000, sí que podrá hacerlo con las últimas versiones de SQL Server, ADO, VBScript y JScript,
MSXML, Internet Explorer (todos en inglés) y NT 4 Service Packs. Todos ellos ofrecen un rendimiento mejorado así como una mayor
confiabilidad.

Sugerencia 26: Ajustar el servidor Web


Varios son los parámetros de ajuste de IIS que permiten mejorar el rendimiento de un sitio. Por ejemplo, en IIS 4.0, a menudo hemos
comprobado que incrementar el parámetro ASP ProcessorThreadMax (consulte la documentación de IIS) puede suponer ventajas significativas,
especialmente en aquellos sitios que tienden a esperar recursos centrales como bases de datos u otros productos de software intermedio como son
los denominados “rascapantallas”. En IIS 5.0, puede que encuentre que activar ASP Thread Gating resulta mucho más eficaz que intentar buscar
una configuración opcional para AspProcessorThreadMax, como es bien sabido.
Para obtener una referencias de gran utilidad, consulte Ajuste de IIS.
Las opciones de configuración óptimas las determinan (entre otros factores) el código de la aplicación, el hardware que se ejecuta en la misma y
la carga del cliente. La única manera de descubrir cuál es la configuración más adecuada es ejecutar pruebas de rendimiento, lo que nos lleva a la
siguiente sugerencia.

Sugerencia 27: Realizar pruebas de rendimiento


Como se señaló anteriormente, el rendimiento es una característica esencial. Si la intención es mejorar el rendimiento de un sitio, es necesario
establecer el objetivo deseado y, a continuación, introducir mejoras progresivas hasta lograr dicho objetivo. No resulta recomendable dejar todas
las pruebas de rendimiento para el final del proyecto, ya que sería demasiado tarde para realizar cambios en la arquitectura y el cliente no estaría
satisfecho en absoluto. Nuestra recomendación es que las pruebas se realicen como parte de la rutina de comprobación diaria; se pueden llevar a
cabo pruebas de componentes por separado, como objetos COM o páginas ASP, o bien del sitio en su totalidad.
Muchos realizan las pruebas de rendimiento de sus sitios Web utilizando un único explorador que iría solicitando las páginas; no obstante,
aunque esto puede dar un resultados muy positivos en cuanto a la respuesta del sitio a las solicitudes, no proporciona información alguna sobre su
rendimiento en situaciones de exceso de carga.
Por regla general, para valorar de forma precisa el rendimiento de un sitio es necesario contar con un entorno de comprobación dedicado que
incluya un hardware que se asemeje a un hardware de producción en cuanto a velocidad del procesador, número de procesadores, memoria,
disco, configuración de red, etc. El siguiente paso consiste en establecer la carga de trabajo del cliente: el número de usuarios simultáneos, la
frecuencia de las solicitudes, los tipos de páginas que se visitan, etc. Si no se tiene acceso a los datos de uso reales, se debe realizar un cálculo
aproximado. Por último, se debe contar con una herramienta que pueda simular las cargas de trabajo de los clientes con anticipación. Con todas
estas armas se puede empezar a formular preguntas como “¿Cuántos servidores necesitaré si cuento con N usuarios simultáneos?” Podrá
descubrir los cuellos de botella y optimizar la situación.
En la sesión siguiente se enumeran una serie de útiles herramientas para realizar pruebas de carga en el Web. Recomendamos sin reservas la
herramienta de carga para aplicaciones Web (WAS). WAS permite registrar secuencias de pruebas y simular cientos o miles de usuarios teniendo
acceso a los servidores Web. WAS proporciona numerosos informes de estadísticas, incluyendo las solicitudes por segundo, las distribuciones de
los tiempos de respuesta y los recuentos de errores. Se trata de una aplicación con una interfaz rica basada en el Web que además permite
ejecutar las pruebas de forma remota.
No olvide consultar IIS 5.0 Tuning Guide (en inglés).

Sugerencia 28: Consultar los vínculos de recursos


A continuación se enumeran algunos interesantes vínculos a recursos relacionados con el rendimiento. Si hay alguno de consulta obligada, ese es
Developing Scalable Web Applications (en inglés).

Recursos

Optimización de secuencias ASP Ajuste de IIS ADO y SQL Server


Componentes ASP y modelos de Componentes de diccionario Estado de la sesión
subprocesamiento
Rendimiento y escalabilidad Herramientas Literatura
Sitios Web de ASP Estilo ASP XML

Optimización de secuencias ASP

 Developing Scalable Web Applications (en inglés)


 Got Any Cache? por Nancy Winnick Cluts (en inglés)
 Maximizing the Performance of Your Active Server Pages por Nancy Winnick Cluts (en inglés)
 15 Seconds: Performance Section (en inglés)
 Enhancing Performance in ASP - Part I por Wayne Plourde (en inglés)
 When is Better Worse? Weighing the Technology Trade-Offs por Nancy Winnick Cluts (en inglés)
 Speed and Optimization Resources por Charles Carroll (en inglés)

Ajuste de IIS

 The Art and Science of Web Server Tuning with Internet Information Services 5.0 (en inglés)
 Leveraging ASP in IIS 5.0 por J.D. Meier (en inglés)
 Tuning IIS 4.0 for High Volume Sites por Michael Stephenson (en inglés)
 Tuning Internet Information Server Performance por Mike Moore (en inglés)
 Navigating the Maze of Settings for Web Server Performance Optimization por Todd Wanke (en inglés)
 Managing Internet Information Server 4.0 for Performance por Hans Hugli (en inglés)

ADO y SQL Server

 Top Ten Tips: Accessing SQL Through ADO and ASP por J.D. Meier (en inglés)
 Improve the Performance of your MDAC Application por Suresh Kannan (en inglés)
 Pooling in the Microsoft Data Access Components por Leland Ahlbeck y Don Willits (en inglés)
 SQL Server: Guías y pruebas comparativas sobre el rendimiento (en inglés)
 Improving the Performance of Data Access Components with IIS 4.0 por Leland Ahlbeck (en inglés)
 Microsoft Data Access Components (MDAC) and ActiveX Data Objects (ADO) Performance Tips por Leland Ahlbeck (en inglés)
 Microsoft SQL Server 7.0 Practical Performance Tuning and Optimization - The Server Perspective por Damien Lindauer (en inglés)
 Microsoft SQL Server 7.0 Practical Performance Tuning and Optimization - The Application Perspective por Damien Lindauer (en
inglés)
 Accessing Recordsets over the Internet por Dino Esposito (en inglés)

Componentes ASP y modelos de subprocesamiento


 Guía del componente ASP por J.D. Meier
 Q243548: INFO: Design Guidelines for VB Components under ASP (en inglés)
 Threading Models Explained por Nancy Winnick Cluts (en inglés)
 So Happy Together? Using ActiveX components with Active Server Pages por Nancy Winnick Cluts (en inglés)
 Developing Active Server Components with ATL por George Reilly (en inglés)
 Agility in Server Components por Neil Allain (en inglés)
 Building High-Performance Middle-Tier Components with C++ por Jon Flanders (en inglés)
 Active Server Pages and COM Apartments por Don Box (en inglés)
 House of COM: Active Server Pages por Don Box (en inglés)
 House of COM: Contexts por Don Box (en inglés)
 House of COM: Performance Trade-offs of the Windows 2000 Component Execution Environment por Don Box (en inglés)
 Building COM Components That Take Full Advantage of Visual Basic and Scripting por Ivo Salmre (en inglés)
 Component Design Principles for MTS (en inglés)

Componentes de diccionario

 Creating a Page Cache Object por Robert Coleridge (en inglés)


 Abridging the Dictionary Object: The ASP Team Creates a Lookup-Table Object por Robert Carter (en inglés)
 Diccionario Caprock (en inglés)
 Site Server Commerce Edition incluye un componente de diccionario (en inglés)

Estado de la sesión

 Q175167: HOWTO: Persisting Values Without Sessions (en inglés)


 Q157906: HOWTO: How To Maintain State Across Pages with VBScript (en inglés)
 XML-based Persistence Behaviors Fix Web Farm Headaches por Aaron Skonnard (en inglés)
 House of COM: Stateless Programming por Don Box (en inglés)

Rendimiento y escalabilidad

 Guía para la creación de sitios Web con la plataforma Microsoft Windows DNA
 Server Performance and Scalability Killers por George Reilly (en inglés)
 Microsoft Visual Studio Scalability Center (en inglés)
 Fitch & Mather Stocks 2000 (en inglés)
 Tuning the FMStocks Application (en inglés)
 High-Performance Visual Basic Apps por Ken Spencer (en inglés)
 Duwamish Books, Phase 4 (en inglés)
 Errores más importantes en el rendimiento de Windows DNA y cómo evitarlos por Gary Geiger y Jon Pulsipher
 Building from Static HTML to High-Performance Web-Farms por Shawn Bice (en inglés)

Herramientas

 Microsoft Web Application Stress Tool (en inglés)


 I Can’t Stress It Enough -- Load Test Your ASP Application por J.D. Meier (en inglés)
 Windows DNA Performance Kit (en inglés)
 Monitoring Events in Distributed Applications Using Visual Studio Analyzer por Mai-lan Tomsen (en inglés)

Literatura

 Professional Active Server Pages 3.0, Wrox Press. (Especialmente el capítulo 26 sobre la optimización del rendimiento de ASP, George
Reilly y Matthew Gibbs) (en inglés).
 Guía de recursos de Microsoft Internet Information Services 5.0 (con Windows 2000 Server Resource Kit), Microsoft Press (en inglés).
 Microsoft Internet Information Server Resource Kit (para IIS 4.0), Microsoft Press (en inglés).
 Programming Distributed Applications with COM and Microsoft Visual Basic 6.0, Ted Pattison, Microsoft Press (en inglés).
 Effective COM, Don Box, Keith Brown, Tim Ewald y Chris Sells; Addison-Wesley (en inglés).
 Developing Web Usability: The Practice of Simplicity, Jakob Nielsen, New Riders (en inglés).

Sitios Web de ASP

 Microsoft TechNet para IIS (en inglés)


 LearnASP.com (en inglés)
 4GuysFromRolla.com (en inglés)
 15Seconds.com (en inglés)
 AspToday.com (en inglés)
 Asp101.com (en inglés)
 AspLists.com. Entre las muchas listas de correo especializadas se incluyen (todas en inglés):
 Fast Code
 ASP Advanced
 Not Newbie
 State Management
 Scalability
 Visual Basic Components
 XML
 C++/ATL Component Building
 UseIt.com: Uso del Web (en inglés)

Estilo ASP

 ASP Best Practices por George Reilly (en inglés)


 ASP Quick Lessons por Charles Carroll (en inglés)
 Planning for ASP por John Meade (en inglés)
 Instrucciones para ASP por J.D. Meier

XML

 Inside XML Performance por Chris Lovett (en inglés)


 Inside MSXML3 Performance por Chris Lovett (en inglés)

Este articulo ha sido leído 10,843 veces

Evitar el cache del navegador

Para evitar que una página se cargue desde el cache del navegador cliente en vez de volver a ejecutarse en el
servidor, solo tenemos que incluir como PRIMERAS instrucciones de nuestra página :

<%
Response.addHeader "pragma", "no-cache"
Response.CacheControl = "Private"
Response.Expires = 0
%>

También podría gustarte