lunes, 7 de septiembre de 2015

Artículos - Buenas Prácticas de Performance en Sitios Web

Buenas Prácticas de Performance en Sitios Web

Uno de los principales atributos de un sitio web es que tenga un Alto Rendimiento, es decir, una buena Performance. En esta sección veremos todo lo necesario para mejorar el rendimiento de nuestros sitios web.


1.   Factores para Medir la Performance de una Aplicación
Los 2 factores más importantes para medir la performance son:
·         Tiempo de Procesamiento, el cual debe ser el menor posible
·         Consumo de Memoria, el cual también debe ser el menor posible

2.   Componentes de un Sitio Web
Los componentes de un Sitio Web los podemos dividir en 2 grandes grupos:
Front-End
Representa el inicio del procesamiento, sobre el cual interactúa el usuario y envía las órdenes al Back-End.
En un entorno web éste se compone básicamente por el Navegador (Browser), el cual procesa los siguientes elementos:
·         HTML, son las etiquetas que especifican lo que hay que Pintar en el Navegador.
·         JavaScript, son Secuencias de Comandos que debe ejecutar el Motor de Scripts.
·         Hojas de Estilos (CSS), son los formatos que se aplicarán a los elementos HTML.
·         Imágenes, son gráficos que debe mostrar el navegador, etc.

Componentes del Front-End de un Sitio Web
Todos estos elementos se encuentran definidos dentro de la página y deben descargarse desde el Servidor Web hacia el Cliente Web (navegador).
Back-End
Representa el final del procesamiento y se encarga de procesar las llamadas del Front-End y devolver resultados.
En un entorno web éste se compone de los Servidores entre los cuales tenemos:
·         Servidor Web, donde se aloja la aplicación web, por ejemplo, el Internet Information Services (IIS) de Microsoft.
·         Servidor de Datos, donde se aloja la base de datos, por ejemplo, el SQL Server de Microsoft.
·         Servidor de Aplicaciones, donde se aloja los Componentes Reusables, por ejemplo, el IIS con Servicios WCF, un Host WCF con Servicios, un Host .NET Remoting con Librerías Remotas, etc.
Componentes del Back-End de un Sitio Web

3.   El problema de la Performance en los Sitios Web
Hace varios años un equipo de investigadores de Yahoo, encabezados por Steve Souders, investigó el problema de la performance, que es: “Cuales son los factores que causan que un Sitio Web sea lento”.
La conclusión a la que llegaron fue que entre el 80 y 85 % de la velocidad de carga de una página está asociada al Front-End y solo del 15% al 20% de problemas lo causa el Back-End.
En síntesis, para dar mayor velocidad a nuestras aplicaciones, hay que optimizar sobre todo la página en el lado del cliente, es decir, HTML, JavaScript, CSS, Imágenes, etc, lo cual se trata con mayor detalle a continuación.


Estadística del Problema de la Performance

4.   Las 14 Reglas de Performance de Steve Souders
En el 2007 Steve Souders arquitecto principal de Yahoo escribió el Libro: “High Performance Web Sites”, en el cual resume en 14 reglas los criterios más importantes para la velocidad de un Sitio Web, además creó una herramienta llamada YSlow que ayuda a medir la performance, que junto a PageSpeed de Google son las herramientas más usadas para este fín.
Las 14 reglas de Steve Souders para que un sitio web tenga un alto rendimiento son:
·         Regla 1: Hacer pocas solicitudes HTTP
·         Regla 2: Usar una Red de Entrega de Contenidos (CDN)
·         Regla 3: Añadir una Cabecera HTTP con el Tiempo de Expiración
·         Regla 4: Comprimir Componentes usando GZIP
·         Regla 5: Ubicar la Definición de Hojas de Estilos al inicio de la página
·         Regla 6: Ubicar la Definición de JavaScripts al final de la página
·         Regla 7: Evitar usar Expresiones CSS
·         Regla 8: Usar JavaScript y CSS externos (archivos)
·         Regla 9: Reducir Búsquedas en Sistema de Nombres de Dominios (DNS)
·         Regla 10: Minificar o Reducir JavaScript y CSS
·         Regla 11: Evitar Redirecciones
·         Regla 12: Remover Scripts duplicados
·         Regla 13: Configurar ETags
·         Regla 14: Guardar en Cache Ajax

5.   Otras 14 Consideraciones de Performance de Steve Souders
En el 2009 Steve Souders escribe otro Libro titulado: “Even Faster Web Sites”, en colaboración con otros especialistas, como:
·         Dion Almaer y Ben Galbraith, líderes de la comunidad Ajax (Mozilla).
·         Douglas Crockford, creador de JSON (Yahoo).
·         Tony Gentilcore, creador de Fasterfox (Google).
·         Dylan Schiemann, co-creador de Dojo Toolkit (SitePen).
·         Stoyan Stefanov, co-creador de YSlow 2.0 y Smush.it (Yahoo).
·         Nicole Sullivan, experta en CSS, co-creadora de Smush.it (W3C)
·         Nicholas C. Zakas, co-creador de YUI Library (Yahoo).
Estas 14 consideraciones para que un sitio web sea siempre rápido son:
·         Consideración 1: Optimizar Ajax
·         Consideración 2: Crear Aplicaciones Web Adaptativas
·         Consideración 3: Dividir la Carga Inicial de la Página
·         Consideración 4: Cargar Scripts sin bloquear el Navegador
·         Consideración 5: Unir Scripts Asíncronos
·         Consideración 6: Posicionamiento de Scripts en línea
·         Consideración 7: Optimizar JavaScript
·         Consideración 8: Escalado con Comet
·         Consideración 9: Aumentando GZIP
·         Consideración 10: Optimizando Imágenes
·         Consideración 11: Fragmentando Dominios Dominantes
·         Consideración 12: Nivelar desde el inicio el Documento
·         Consideración 13: Usar escasamente los iFrames
·         Consideración 14: Simplificar los Selectores CSS

6.   Principales Reglas de Performance en Sitios Web

·         Regla 1: Hacer la menor cantidad de solicitudes (HTTP Request)
Para cumplir con esta regla se deberá bajar la menor cantidad de archivos del servidor al cliente, por lo que se debe tener en cuenta lo siguiente:
Ø  Tratar de enviar solo uno o dos archivos de JavaScript. De preferencia debe ser un solo archivo conteniendo solo las funciones usadas en dicha página. Sin son 2 archivos JS uno será genérico (compartido para varias páginas) y otro específico (solo para dicha página).
Ø  Tratar de enviar solo uno o dos archivos de Hojas de Estilos. De preferencia debe ser un solo archivo conteniendo solo los estilos usados en dicha página. Sin son 2 archivos CSS uno será genérico (compartido para varias páginas) y otro específico (solo para dicha página).
Ø  Tratar de Reducir el número de imágenes enviadas al cliente usando Sprites o si las imágenes son pequeñas enviando un flujo serializado como Base64 String.
Comentarios
Actualmente, la mayoría de Sitios Web No cumplen con la regla más importante de la performance, por las siguientes razones:
Ø  Uso de varios archivos de JavaScripts de Frameworks como jQuery, jQueryUI, PlugIns, etc; la mayoría de veces solo por usar unas cuantas características (funciones) de cada uno en la página, innecesariamente se bajan todos los archivos con todas las funciones.
Ø  Uso de varios archivos de Hojas de Estilos de Frameworks de Diseño Web Adaptativo (Responsive Web Design) como Bootstrap, jQuery Mobile, etc; la mayoría de veces solo por usar unas cuantas características (estilos) de cada uno en la página, innecesariamente se bajan todos los archivos con todos los estilos.
Ø  Uso exagerado de archivos de imágenes para mejorar la apariencia de la página, sin importar que por cada archivo mostrado se tenga que hacer un viaje desde el cliente hacia el servidor para traerla y mostrarla.
Ø  El hacer Bundling (Fusión de Archivos) para los JS y CSS No es la mejor solución, ya que si bien es cierto se envía un solo archivo al cliente se incumple la segunda regla ya que se envía mucho contenido.

·         Regla 2: Enviar la menor cantidad de bytes al cliente
Esta segunda regla requiere enviar la menor cantidad de datos del servidor al cliente, incluyendo: HTML, JavaScript, CSS, Imágenes, etc; para lo cual debemos tener en cuenta lo siguiente:
Ø  Solo incluir las funciones de JavaScript que se van a usar en la página.
Ø  Solo incluir los estilos que se van a usar en la página.
Ø  Una vez seleccionado solo las funciones necesarias, minificar el archivo JS.
Ø  Una vez seleccionado solo los estilos necesarios, minificar el archivo CSS.
Ø  Minificar el HTML de la página que viene del servidor, si se usa controles de lado del servidor se deberá crear un Modulo HTTP que intercepte el contenido y minifique el HTML.
Ø  Optimizar las imágenes antes de enviarlas al cliente, reduciendo su tamaño y escogiendo un formato comprimido que no pierda la calidad, por ejemplo el formato png o web-p.
Comentarios
Actualmente, la mayoría de Sitios Web tampoco cumplen con la segunda regla más importante de la performance, por las siguientes razones:
Ø  Cuando usan archivos de JavaScript de terceros, no seleccionan solo las funciones que necesitan en la página y las copian a su único archivo JS, sino que se descargan todos los archivos con todas las funciones tal cual venga en el Framework JavaScript que están usando.
Ø  Cuando usan archivos de hojas de estilos de terceros, no seleccionan solo los estilos que necesitan en la página y las copian a su único archivo CSS, sino que se descargan todos los archivos con todos los estilos tal cual venga en el Framework Responsive Web Design que están usando.
Ø  Minificar los archivos JS con todas las funciones que vienen en los Frameworks de JavaScript, las cuales en su mayoría no se usan, es una solución incompleta, lo mejor es minificar solo las funciones que se usan y no enviar en vano tanto contenido.
Ø  Minificar los archivos CSS con todos los estilos que vienen en los Frameworks Responsive, los cuales en su mayoría no se usan, es una solución incompleta, lo mejor es minificar solo los estilos que se usan y no enviar en vano tanto contenido.
Ø  Muchos desarrolladores usan Controles de lado del Servidor que generan demasiado HTML, mejor sería enviar solo los datos necesarios y pintarlos en el cliente. Pero cuidado, no usar HTML, XML ni JSON, si queremos reducir al máximo el ancho de banda solo debemos enviar los datos sin metadata, por ejemplo, separados por un caracter, inclusive se pueden enviar imágenes como Base64String.

·         Regla 3: Hacer Llamadas Asíncronas Ligeras
Es muy importante mantener siempre la disponibilidad de la aplicación, es decir, por ejemplo, que el usuario siempre pueda trabajar con la interface de usuario. Para esto podemos usar la programación asíncrona, en el caso de las llamadas desde el cliente al servidor generalmente se usa Ajax, para lo cual debemos tener en cuenta lo siguiente:
Ø  Usar XMlHttpRequest (XHR) para hacer llamadas asíncronas en forma nativa, ya que es un estándar de la W3C que actualmente es soportado por todos los navegadores. Los que usan jQuery Ajax, Microsoft Ajax, Ajax Control Toolkit, etc, están usando una librería que internamente usa XHR. Por ejemplo, los métodos de jQuery: $.get, $.post, $.json y $.ajax son llamadas a los métodos open y send de XHR.
Ø  Enviar y recibir datos como cadenas (Text) al hacer llamadas asíncronas, ya que solo ocupa un 7% de todo el HTML (100%), mientras las vistas parciales con HTML son el 50% aproximadamente y si se usa JSON sería el 25% aproximadamente. Es decir, creando un Serializador en el Servidor (código C# en .NET) se puede convertir objetos a cadenas y reducir el ancho de banda en casi un 93%, logrando mayor velocidad de carga de la pagina, aunque tengamos que pintar los controles HTML por JavaScript.
Ø  No escribir código en el inicio de la página, dejarlo en un método que se llame en forma asíncrona, debido a que la primera vez siempre se demora la pagina en cargar y mas el código a ejecutar seria más lento, en cambio, si enviamos la pagina sin ejecutar ningún código al inicio, dejamos que cargue en el navegador y recién hacemos la llamada en forma asíncrona (segundo plano) usando XHR y devolviendo cadenas con los datos que se pintaran como HTML usando JavaScript.
Comentarios
Esta tercera regla también es ignorada por que en muchos casos se hace lo siguiente:
Ø  Se usa jQuery como librería de JavaScript para hacer operaciones asíncronas. En realidad, no fuera malo si solo se seleccionara los métodos que se van a usar, pero casi todos no lo hacen y se trabaja con el archivo JS completo, es por eso, que mejor sería usar directamente una función que use XmlHttpRequest.
Ø  Actualmente, en ASP.NET MVC, la mayoría para trabajar en forma asíncrona usa vistas parciales que envían HTML o jQuery que envía JSON (con metadata) el cual es pintado en el cliente. Esta segunda forma es mejor que la primera, pero la más óptima es que se envíe solo los datos (sin metadata) y se pinte en el cliente.
Ø  Siempre se implementa Ajax en el regreso de la pagina (PostBack), por ejemplo, al dar clic a un botón de consulta o al grabar; pero es indispensable que también se haga en el inicio, ya que es aquí donde se demora más y se necesita que el usuario vea rápido la pagina web y no se quede en blanco el navegador.

·         Regla 4: Optimizar las operaciones con Bases de Datos
Esta regla implica trabajar en forma desconectada la explotación de datos y en forma conectada por lotes la actualización de datos, para mayor detalle seguir las siguientes directivas:
Ø  Las operaciones con datos como búsquedas o filtros, paginación, ordenación, exportación de datos a texto, Excel, etc, se pueden realizar solo en el cliente usando JavaScript, en vez de estar yendo al servidor para realizar tareas con datos que muchas veces No cambian constantemente. Por ejemplo, el ubigeo, al seleccionar el Departamento, filtrar las Provincias y al seleccionar la Provincia filtrar los Distritos; muchos se van hasta el Servidor de Base de Datos, otros hasta el Servidor Web, cuando fácilmente podría hacerse en el cliente.
Ø  Las operaciones de actualización de datos, como inserción, actualización y eliminación generalmente se hacen en forma conectada, pero de preferencia debe hacerse por lotes, es decir no por cada registro sino por un grupo de registros, por ejemplo los mostrados en una página.
Ø  Si hay que insertar o actualizar muchos registros, por ejemplo más de 100, es preferible realizar copias masivas si el origen de datos es SQL Server u Oracle Server, para lo cual se almacena los datos en una tabla y se envía con la clase BulkCopy de ADO.NET. Otra alternativa sería enviar una cadena separada por caracteres especiales y tener un Procedimiento Almacenado que las separe y las inserte o actualice en su tabla destino.
Comentarios
Esta cuarta regla también no se cumple por las siguientes razones:
Ø  La mayor parte de las consultas a todo tipo de datos, desde el sexo, estado civil, ubigeo, tipo de documentos comerciales, empleados, clientes, proveedores, etc.; se realizan en forma conectada, siendo para la mayor parte de casos innecesario ya que los datos no varían constantemente. Algunos guardan los datos en variables de Sesión en el Servidor Web, a veces en un TempData en MVC para no ir hasta la BD, pero otros, si van a consultar a la Base de Datos creando conexiones constantemente y saturando el ancho de banda de la red.
Ø  En el caso de las actualizaciones, la mayoría trabaja en forma individual, es decir, realiza los cambios en cada registro, en vez de hacerlo por lotes o para un grupo de registros consumiendo una sola conexión a la base de datos, sobre todo si es gran cantidad de registros que se quiere actualizar o insertar.

7.   Arquitectura de Desarrollo Web de Bajo Rendimiento (ADWBR)
Una Arquitectura de Desarrollo Web que produce un Bajo Rendimiento (Low Performance) es aquella que tiene las siguientes características:
·         Está Orientada al momento del Desarrollo o a facilitar la Construcción, por lo que usa intensivamente Librerías o Frameworks de terceros.
·         Se piensa que favorece al Desarrollador ya que al usar bloques de código pre-construido (Frameworks) el tiempo de desarrollo es menor que si se hace todo desde cero.
·         Cada página descarga muchos archivos en el cliente, porque usa muchas librerías de JavaScript, muchos archivos de CSS y muchas imágenes que se bajan de uno en uno o de dos en dos, dependiendo del navegador que se use.
·         Se descarga mucho contenido, por ejemplo todo el HTML con los datos a presentar, todas las funciones JavaScript se usen o no y todos los estilos se usen o no. Eso ocurre por usar Frameworks de terceros y no ser selectivo, hay cosas que no se usan pero todo viaja.
·         Usan llamadas asíncronas pesadas, ya que envían muchos datos de ida y de vuelta, algunos usan XML como formato de transporte y otros reducen el ancho de banda usando JSON, pero igual se puede mejorar mas.
·         Hacen operaciones No óptimas con Bases de Datos, ya que todo se hace en forma conectada usando Frameworks pesados como Entity Framework, cuando trabajan en forma desconectada usan DataSet y DataTables, y cuando actualizan gran cantidad de registros lo hacen en forma individual ejecutando muchos comandos.
Componentes de una Arquitectura de Desarrollo Web de Bajo Rendimiento

8.   Arquitectura de Desarrollo Web de Alto Rendimiento (ADWAR)
Una Arquitectura de Desarrollo Web que produce un Alto Rendimiento (High Performance) es aquella que tiene las siguientes características:
·         Está Orientada al momento del Despliegue o a facilitar la Ejecución, por lo que se hace todo desde cero y nativo.
·         Favorece al usuario final, ya que la aplicación web será muy rápida, pero también puede favorecer al desarrollador ya que no habrá problemas de soporte post producción.
·         Cada página descarga pocos archivos en el cliente, solo un HTML, un JavaScript, un CSS, y las Imágenes se envían en un solo Paquete o como un archivo Sprite.
·         Se descarga poco contenido, por ejemplo solo viaja los datos como cadenas sin HTML y por JavaScript se crea el HTML como cadena y se pinta una vez en el DOM, el archivo JavaScript solo tiene las funciones que se van a usar en la pagina, el archivo CSS solo los estilos usados por esa página y las Imágenes están optimizadas (comprimidas).
·         Usan llamadas asíncronas ligeras mediante XmlHttpRequest (XHR), enviando los datos como cadenas tanto en la ida como en la vuelta, esto permite ahorrar en más de 90% el ancho de banda logrando mayor velocidad.
·         Hacen operaciones óptimas con Bases de Datos, ya que se usa ADO.NET para el acceso a datos, las consultas se trabajan en forma desconectada con Listas de Objetos en el Servidor Web y en el Cliente con Matrices en JavaScript. Las actualizaciones se hacen por lotes y para gran cantidad de registros se usa BulkCopy o Cadenas en el Procedimiento Almacenado.
Componentes de una Arquitectura de Desarrollo Web de Alto Rendimiento

Comentario Final

Se que muchos no compartiran algunas ideas de este artículo, ya que esta muy arraigado los estándares de reusabilidad que son diferentes a los de performance que es lo que yo propongo, y el cual en los últimos meses me he encargado de difundir, Tengo una nueva arquitectura que estoy trabajando basada en la Performance.

Los interesados en conocer la parte práctica y la comparación de resultados entre la arquitectura tradicional y la arquitectura que propongo pueden asistir este Sabado 12 de Setiembre de 2:00 pm a 2:50 pm en el CEPS de la UNI, del cual dejo la relación de charlas: