Desarrollo de Aplicaciones Web de Alto Performance

Publicado en

Ante la importancia que han cobrado las aplicaciones web, es necesario que los desarrolladores web adquieran una cultura orientada al performance, ya que en el entorno web las aplicaciones son muy sensibles a factores incontrolables tales como el ancho de banda del cliente, ubicación geográfica, número de usuarios concurrentes, etcétera.

El performance, hablando de desarrollo web, se refiere al grado de agilidad y respuesta con que se desempeña un sitio web. En este artículo veremos algunas buenas prácticas para mejorar el performance de las aplicaciones web. En algunos casos utilizo referencias a .Net porque es la plataforma que mejor conozco, pero quienes utilicen otras tecnologías seguramente encontrarán analogías que correspondan.

Evitar el uso de imágenes pesadas.
Internet es un entorno multimedia por excelencia: video, música, imágenes, animaciones web. Los elementos básicos de una página
web son texto e imágenes, pero no es recomendable manejar imágenes muy pesadas ya que la página puede llegar a tardarse bastante en cargar. Los formatos adecuados de imágenes en ambiente web son:
GIF. Es el único formato que permite realizar animaciones. Soporta imágenes de pocos colores (hasta 256). Es bueno para imágenes sencillas (no fotografías).
PNG. Es un formato mejorado de GIF, ya que presenta un algoritmo de compresión sin perdida de calidad en la imagen. IE6 no lo soportaba pero prácticamente todos los navegadores modernos ya lo soportan.
JPEG. El rey de las imágenes ligeras. Al contrario de GIF, su algoritmo de compresión elimina información y por ende decrece la
calidad de la imágenes (en muchas ocasiones esto no importa porque la pérdida de información no es perceptible para el ojo humano).

Los formatos de imágenes inadecuados para ambiente web son:
BMP. El BitMaP es el formato nativo del sistema operativo Windows de Microsoft. Define los valores de cada pixel, uno a uno,
de abajo a arriba y barriendo las líneas de izquierda a derecha. Su gran problema es que genera archivos enormes.
TIFF. Formato propiedad de Adobe Systems empleado para intercambiar fotografias entre distintas aplicaciones y plataformas.
Comprime las imágenes sin pérdida de calidad pero el peso sigue siendo grande en comparación a otros formatos.
PSD. Formato utilizado por el popular editor de imágenes Photoshop. No utiliza compresión y se emplea para guardar la imagen
durante el proceso de edición, pues mantiene toda la información sobre capas sin acoplar.

Nota: HTML 5 soportará formatos de imagen vectoriales, que son una excelente opción para diagramas y trazos ya que son muy
ligeros y no pierden calidad al aumentar sus dimensiones.

Tener cuidado con controles y wizards

 

.Net proporciona una seria de controles para “facilitar” la vida al programador, por ejemplo el control SQLDataSource. Son controles
muy sencillos ya que al solo requerir un comando SQL, cualquier persona podría establecer una conexión a base de datos y traer datos. El problema con este tipo de controles es que son pesados, sin mencionar que hay que introducir la instrucción SQL dentro del control dando origen a una mala practica de programación: el código embebido. Al tener nuestras paginas hechas con este tipo de controles quedan ocultas todas las instrucciones SQL y al darle mantenimiento hay que entrar a cada control a averiguar qué instrucción SQL se esta ejecutando, lo cual hace que el mantenimiento se vuelva complicado, sin mencionar que el performance de la pagina se ve afectado.

Arquitectura basada en capas
La arquitectura en capas nos permite reutilizar código, y por ende, mejorar el performance. He llegado a ver aplicaciones que repiten una y otra vez el mismo código en cada pagina encargado de abrir la conexión a la base de datos y de proporcionar los comandos necesarios para obtener, actualizar, insertar o eliminar datos en vez de establecer toda esta estructura en capas que sean utilizadas una y otra vez en forma genérica para cualquier página. De esta manera nos ahorraremos bastante codificación, sin mencionar toda la carga de texto que le quitamos a las páginas. No es de sorprender que este tipo de técnicas se refleje en una página mucho más ágil y responsiva.

Programar eficazmente
Existen muchos ejemplos de cómo una mala programación puede afectar al performance de un sitio web. Imaginemos que estamos
desarrollando un carrito de compras. Una mala estrategia seria que por cada producto que agregue el usuario al carrito, lo guardáramos en la base de datos. Esto implicaría obtener una conexión a la base de datos y realizar INSERTs una y otra vez. Ahora multipliquemos esta tarea por decenas o cientos de usuarios que estarían en nuestro sitio al mismo tiempo. Sin duda que el performance de nuestra pagina se vería muy afectado. Una mejor aproximación seria almacenar cada producto que introdujo el usuario en un XML. De esta forma una vez que el usuario confirma la compra, entonces mandamos la cadena XML con todos los productos a un store procedure en SQL que se encargue de leer el XML mediante un cursor e introducir los productos a nuestra tabla, uno a la vez. Para SQL esto implica una sola tarea: ejecutar un store procedure. De esta forma introducimos todos los productos de un solo golpe. Finalmente, volviendo a la estrategia inadecuada: ¿Qué pasa si el usuario se arrepiente y cancela el pedido? Tendríamos que eliminar de la base de datos la información que introdujo. No tiene sentido introducir información para después eliminarla. Además, ¿que pasaría si el usuario simplemente abandona el carrito de compras y nunca le da cancelar? Lo que pasaría es que nos quedaríamos con basura en nuestra base. Por eso es mejor auxiliarse de un XML en estos casos, para manejar de manera elegante y efectiva este tipo de situaciones.

Aligerar la carga de trabajo
La mayoría de las plataformas y lenguajes modernos para desarrollo web nos permiten manipular los objetos como deseemos, desde conversiones a tipos de datos hasta colecciones de objetos, matrices, sobrecarga, polimorfismo, etcétera. Pero en muchas
ocasiones es innecesario hacer esto en el nivel de lenguaje de programación, cuando ciertas cosas se pueden manejar desde origen, es decir desde la base de datos. Imaginemos que necesitamos mostrar información sobre cálculos monetarios relacionados
con el Afore de una persona. Para SQL es más natural y sencillo hacer los cálculos de un solo golpe sumando, multiplicando o restando columnas porque toda la información que necesita la tiene a su disposición, mientras que si lo hacemos a nivel de programas hay que pasarles la información para que se vaya procesando una por una.

Modularizar
Imaginemos que estamos desarrollando una página donde se manejan cotizaciones, remesas y comisiones. Sin duda que sería una pagina llena de controles y con bastante código. Es mejor separar las funcionalidades y crear una pagina para el manejo de las cotizaciones, otra pagina para las remesas y otra para las comisiones. O como se diría en lenguaje coloquial: divide y vencerás. A esta técnica se le conoce como modularizacion y hay que tomarla en cuenta no solo para separar páginas, sino también funciones, procesos y módulos en aras de un mejor performance.

Usar tipos de datos adecuados
Cuando definimos una tabla, variable o constante debemos asignar un tipo de dato que indica los posibles valores que podrá almacenar. Los desarrolladores principiantes pueden verse abrumados por todos los tipos de datos que los manejadores de bases de datos ofrecen y verse tentados a simplemente utilizar dos tipos de datos, el integer para números y varchar para texto. Por ejemplo, si tuviéramos que almacenar valores numéricos del 1 al 10 y utilizáramos el tipo de datos integer, seria como usar la caja de un trailer para almacenar un arete o un anillo. No hay nada más dañino para una aplicación que hacer esto. Si existen diversos tipos de datos es porque cada uno tiene su razón de ser y aplicar los tipos de datos adecuados nos asegurara un mejor rendimiento en nuestra aplicación. Cada RDBMS tiene sus propios tipos de datos, por lo que se recomienda revisar que tipos de datos maneja la base de datos con la que nos toque trabajar en ese momento.

Controlar el uso de flash
Una de las características más molestas de las páginas web es el “flasheo” o “pantallazo” cada vez que sucede algún evento como
dar clic en un botón por ejemplo. Los controles de flash solo deben usarse cuando realmente tengan sean necesarios y no haya mejor opción.

Usar controles ligeros
Si estás usando ASP.Net para desarrollar tus aplicaciones web, dispones de una serie de controles muy buenos para mostrar datos
tales como el Gridview, DataList y FormView, pero estos generan bastante código HTML tras bambalinas. El control Repeater es mucho más ligero y en la mayoría de los casos suficiente en términos de funcionalidad.

Limpiar lo que ya no se usa
Cada vez que creemos la instancia de un objeto, después de que lo hayamos usado, hay que especificarle que ya no lo vamos a necesitar. En ASP .Net esto se hace mediante la instrucción objeto = nothing. De esta forma el Garbage Collector se dará cuenta de que ese espacio de memoria que estaba usando el objeto ya no se usa y lo liberara. Un buen lugar para poner esta instrucción es después de la instrucción Finally, la cual garantiza que siempre pasara la ejecución de código por ahí.

Validación del lado del cliente
Siempre será más ligero validar datos del lado del cliente con Javascript que validar datos del lado del servidor, aunque es mas seguro hacerlo del lado del servidor. Quizás podríamos dejar las validaciones del lado del servidor para cuestiones críticas como un número de tarjeta de crédito.

Enviar datos entre páginas con SERVER.TRANSFER
Asp.Net presenta las siguientes instrucciones para navegar y enviar datos entre paginas: Response.Redirect y Server.Transfer. Response. Redirect deberá usarse cuando:
• Queramos redirecccionar la petición a paginas HTML en nuestro servidor o algún otro servidor web.
• No nos preocupe hacer vueltas adicionales en cada petición al servidor.
• No necesitemos preservar la cadena de consulta (Query string) ni las valores de las variables de la petición original.
• Queramos que nuestros usuarios puedan ver la URL a donde redireccionemos en su navegador.
Server.Transfer deberá usarse cuando:
• Queramos transferir una petición de la pagina actual a otro
componente en el mismo servidor.
• Queramos evitar innecesarias vueltas al servidor.
• Queramos mantener la cadena de consulta (Query string)
y las variables.
• No necesitemos mostrar la URL verdadera a donde estamos direccionando la petición.

Es evidente que Server.Transfer es más eficaz al no dar vueltas innecesarias al servidor, mientras que response.redirect se debe usar solo en ciertas situaciones.

Concatenar cadenas efectivamente
La instrucción para concatenar cadenas de ASP.Net StringBuillder es mas rápida que las técnicas mas rudimentarias como string + string.

Cerrar dentro de finally
Si abrimos una cadena de conexión o algún archivo debemos asegurarnos de volver a cerrarlo al final del método después de la instrucción Finally.

Controlar el uso de try ... catch
La instrucción try-catch es muy buena ya que nos permite atrapar situaciones de excepción. Sin embargo esto no quiere decir que
debamos usarlas en todos los métodos. Solo deben de usarse en aquellas situaciones que puedan ser susceptibles de error como al
intentar abrir algún archivo o al intentar ejecutar algún comando relacionado con la base de datos. También debemos evitar ser repetitivos a pesar de que la situación lo justifique, por ejemplo si usamos un try-catch en un método, y este método manda llamar
a otro, ya no será necesario volver a poner el try-catch de nuevo en el segundo método.

Conclusión
Debido a que las aplicaciones web son muy sensibles a factores externos, debemos prestar atención en el cuidado del performance.
En un principio las mejoras pueden parecer imperceptibles, pero conforme aumenta la cantidad de usuarios concurrentes, es donde
se ve si la aplicación sigue siendo ágil o se vuelve pesada. Cualquier cosa que descubramos que ayude a mejorar el rendimiento y respuesta de nuestra aplicación siempre será bienvenida

Referencias:
[1] C. Darie & K. Watson, Beginning ASP. Net 2.0 E-Commerce in C#, Apress, 2006
 

 

Bio

Ricardo Rangel Ramírez es Licenciado en Informática egresado de la Universidad de Ecatepec. Ha desarrollado software en plataforma .Net para diferentes empresas. Actualmente labora en el Departamento de Sistemas de Stanhome de México y en proyectos independientes. Sus principales habilidades son la gestión y explotación de información, y el análisis, diseño y desarrollo de sistemas