Posts Tagged ‘rendimiento’

h1

Mejorando el rendimiento : Comprimir los componentes

31 enero 2009

Se puede reducir notablemente el tiempo de respuesta y peticiones HTTP a través de la red reduciendo el tamaño de los elementos, aunque evidentemente hayan más factores como el ancho de banda, la proximidad, los puntos de intercambio y demás, que son independientes de los desarrolladores.

La compresión de ficheros se ha utilizado durante décadas para mejorar la transferencia en emails, FTP desde la versión HTTP/1.1 los navegadores soportan cla compresión de ficheros. Hay dos formatos el delate y gzip, siendo el segundo el más popular y óptimo de los dos. Se pueden comprimir los documentos html, las css, los scripts, y aunque no se suele hacer, los ficheros XML y JSON, las imágenes y los PDF, ya están comprimidos por lo cual no es necesario hacerlo de nuevo, ya que supone un coste de los recursos de la CPU innecesario. Hay que tener en cuenta el tamaño de los ficheros a comprimir sobre todo, ya que, a lo mejor el coste de descomprimir sea más alto que el coste en la transferencia del mismo. Normalmente se comprimen los ficheros mayores de 1 ó 2 Ks, lo cual se puede controlar a través de la directiva mod_gzip_minimun_file_size.

Existe un problema cuando se usan los proxies, ya que, si se hace una petición desde un navegador que permite la compresión y las sucesivas desde uno que no lo permite el segundo no podrá ver el contenido, si el orden de las peticiones es al revés, no es tan grave porque nadie deja de ver el contenido. Para solucionar este problema se debe conseguir que el proxy varíe las repuestas a las peticiones ya que la compresión depende de cada uno de los navegadores. Podemos cachear varias respuestas, es decir, tener una respuesta cacheada con los componentes comprimidos y otra con los componentes normales. Esto se hace mediante la directiva Vary: Accept-Encoding.

Otro problema pueden ser los navegadores y sus versiones,  ya que algunas permiten la compresión y otros que no, por lo cual al vary se le añade User-Agent, para que almacene una respuesta cacheada dependiendo del navegador y la versión.

Anuncios
h1

Mejorando el rendimiento: Expires Header

29 enero 2009

Una técnica que nos ayuda mucho a mejorar la experiencia del usuario a la hora de cargar la página es que el navegador del usuario cachee la información, en muchos de los casos, se suele cachear sólo las imágenes, pero es recomendable que se cacheen todos los elementos posibles, como css, scripts y demás porque así mejoramos la carga. Evidentemente esto conlleva algunos “problemas”, por ejemplo, si el usuario limpia la caché, se perderá la información que tenga almacenada o si es la primera vez que se mete en la página, el tiempo de carga no mejora, pero ante esto no se puede hacer nada, o sí se modifica algo y la fecha de expiración no se ha cumplido todavía ¿Qué pasa? para algunos temas hay solución y para otros no. A continuación hablaré un poco de la caché del navegador.

Si usamos la cache del navegador, todos los elementos cacheados serán consultados en disco en vez de realizar una petición HTTP, por lo cual se reducirá mucho el tiempo de carga, normalmente se utiliza el expires header y se le pone una fecha y hora hasta la cual la información cacheada es válida.  Una alternativa es Cache-Control, que se introdujo en HTTP/1.1 para cubrir las limitaciones del Expires Header, ya que, éste, usa una fecha específica, lo cual implica una sincronización más estricta, a demás de que se debe comprobar continuamente dicha fecha. En cambio el Cache-Control usa la directiva max-ege para especificar cauanto tiempo un elemento esta en cache. Con esta directiva se define el tiempo en segundos si es menor que ese número de segundos se usará el elementos. De todas formas se tiene que definir ambos cosas el Expires-Header y el Cache-Control dónde prevalecerá el max-age, de todas formas, aunque el Cache-Control supla los problemas del Expires Header, tenemos que tener cuidado con el mantenimiento y la sincronización. Existe un módulo de Apacha, el mod_expires permite usar el Expires-Header con un formato similar al del max-age, mediante la directiva ExpiresDefault. Gracias a esta directiva, la sincronización nos da un poco igual, ya que es relativa a la petición. Lo cual hace esta la mejor opción.

Uno de los grandes problemas que podemos encontrarnos es que pasa si modificamos alguno de los elementos que indicamos que se cacheen, al estar en la cache y dentro de plazo el usuario no obtendrá los cambios. Para solucionar esto, tenemos que cambiarle el nombre a los ficheros, el problema se encuentra en que si no construimos nuestras páginas dinámicamente, o de alguna forma mediante la cual sólo haya que cambiar los nombres en un sitio centralizado, esto puede ser un suplicio.

h1

Mapa de Imágenes o Image Map

15 diciembre 2008

Siguiendo con la serie de entradas sobre rendimiento web, quería explicar un poco más que es un mapa de imágenes. Un mapa de imágenes es una imagen con areas sobre las que se puede establecer un link. Las hay de dos tipos del lado del cliente y del lado del servidor,  las del lado del cliente son mejores de cara al rendimiento, ya que, no requiere de una petición al back-end, aunque son menos flexibles que las del lado del servidor.

A continuación pondré un código de ejemplo de un mapa de imágnes del lado del cliente. Para usar esta técnica lo único que hay que hacer es establecer las coordenadas de cada area y el link de dicha area. Por ejemplo:

<MAP NAME=”map1″>
<AREA  HREF=”enlace1.html” ALT=”alt1″ TITLE=”titulo1″   SHAPE=RECT COORDS=”6,116,97,184″>
<AREA  HREF=”enlace2.html” ALT=”alt2″ TITLE=”tutilo2″  SHAPE=CIRCLE COORDS=”251,143,47″>
</MAP>

<IMG SRC=”imagen.gif”  ALT=”alt de la imagen” BORDER=0 WIDTH=300 HEIGHT=300 USEMAP=”#map1″><BR>

En la configuración del mapa vemos los siguientes atributos:

href: url del enlace

alt: alt del enlace

title: título del enlace

shape: forma de la figura que puede ser:  default|rect|circle|poly

coords: Que son las coordenadas del area que se definde de la siguiente forma:

  • rect: left-x, top-y, right-x, bottom-y.
  • circle: center-x, center-y, radius. 
  • poly: x1, y1, x2, y2, …, xN, yN. La primera x e y deberían ser la misma que xN e yN para cerrar el polígono.
h1

Consejos para mejorar el redimiento de una web II

11 diciembre 2008

Como dije en la otra entrega, la mayor parte del tiempo de respuesta se emplea en realizar peticiones HTTP para la descarga de los distintos componentes más que en el propito HTML, por lo tanto si reducimos el número de elementos a descargan se reduciran el número de peticiones sin que esto signifique tener que deshacernos de elementos y, por tanto, perder calidad en el diseño. Las técnicas que se pueden utilizar para eso son:

  • Mapa de Imágenes: Si tenemos muchos enlaces con imagenes, tendremos que realizar muchas peticiones para obtener todas las imáganes, en cambio, si usamos un mapa y le asociamos todos los enlaces, sólo tendremos que realizar una petición HTTP para obtener los enlaces. Existen dos tipos de mapas de imagenes, los del lado del servidor y los del lado del cliente, los mas típicos ya que no requieren de ningún back-end.
    Está técnica tiene un problema, el área se tiene que definir a mano y es tedioso y próblematico además de que sólo pueden ser rectangulares y no
    se pueden crear de forma dinámica ya que el DHTML falla en IE.
  • CSS Sprites: La idea es que todas las imágenes se combinan en una y mediante las hojas de estilos se muestra la zona de la imagen que se desse. Evidentemente, se reduce el número de peticiones, de forma significativa y son más flexibles que los mapas de imágenes. Así mismo, y aunque parezca mentira, el tamaño de la imagen combinada es menor que la suma de todas las que la forman, ya que, se reduce la información de las imágenes (tablas de color, información del formateo, etc…)
  • Scripts y css combinados: Es recomendable usar ficheros externos para los scripts y los css y aunque a veces se tienda a modularizar en muchos ficheros css y js, esto influye negativamente en el rendimiento porque se traduce en más peticiones HTTP. De todas formas, esto nos puede soñar extraño a todos los
    desarrolladores, siempre nos han metido en la cabeza la modularización por todas las ventajas que conocemos, además de que estaríamos cargando
    información innecesaria en la página. 
    Por lo tanto, lo que debemos hacer es, analizar un poco y crear un proceso para generar un fichero que nos devuelva la combinación de ficheros javascript necesaria para una página en concreto.

Todo esto reduce el tiempo de respuesta para usuarios que acceden por primera vez a la página web, es decir, aquellos usuarios que no tengan elementos en caché y demás.

h1

Consejos para mejorar el redimiento de una web I

10 diciembre 2008

Llevo muchos años trabajando en el mundo web y uno de nuestros objetivos es mejorar el rendimiento de cara al usuario final, para ellos se usan muchas técnicas, pero las más efectivas son las que mejoran el front-end de la aplicación y la más sencilla. También se pueden realizar cambios sobre el back-end de la apliación, pero esto puede llegar a suponer grandes cambios en el código de la misma y no supone un cambio en tan grande como las técnicas que se utilizan cuando mejoramos el tiempo de respuesta desde el front-end.

Hay muchos factores que influencian en el rendimiento de nuestra web, entre otros tenemos:

  • Descarga del html y otros componentes (imágenes, css, scripts…)
  • Parseo por parte del navegador del html, javascript y css
  • Las peticiones HTTP
    • Hay que hacer especial hincapié en las peticiones pararelas, según la especificación del protocolo, sólo se pueden descargar dos componentes de manera simultánea de un mismo hostname (porque así lo define la especificación) y la mayoría de las webs las resuelve un sólo hostname, con lo que se tienen que hacer múltiples peticiones para la descarga de todos los elementos.

Hay muchas cosas que influyen y es muy díficil definirlas todas, pero lo que si que puedo asegurar es lo que no influye en el redimiento, y esto es la descarga del html, ya que es tan sólo un 5% total del tiempo de carga.

Mi intención es explicar distintas reglas que podemos seguir para la consecucíón de nuestro objectivo, para ello escribiré un mini manual en una serie de posts, de los cuales este es el primero. En el que intentaré explicar un poco los factores más determinantes en el rendimiento de la web del protocolo HTTP.

El protocolo HTTP  lo definieron la W3C y el IETF y está definida en el RFC 2616 y aunque va por la versión 1.1 todavía hay muchos navegadores que usan la 1.0. Éste es un protocolo cliente/servior basado en peticiones y respuestas. El navegador hace una peticion de una URL y el servidor que hospada esa url le manda un
 HTTP request. Todo mediante sencillos ficheros de texto y con diferentes tipos de peticiones, GET., POST, HEAD, PUT, DELETE, OPTIONS y TRACE. De las cuales el más común es el GET y por eso será el que explique con mayor detenimiento. Algunas de las características de las peticiones GET son:

  •  Compresión: El tamaño de las respuestas se reduce si el navegador y el servidor soportan  la compresion. Mediante la cabecera Content-encoding mediante las que el servidor averigua si el navegador que realiza la búsqueda soporta la compresión. 
  • GET condicionales: Si el navegador tiene una copia en la cache de los elementos pero no esta seguro de que todavía sean validos, manda un GET condicional, si sigue siendo valido, la carga tarda menos y mejora la experiencia del usuario. La forma en la que se suele comprobar si la cache sigue siendo válida es mediante la fecha de modificación, la cuál el navegador conoce basándose en la cabecera Last-Modified, entonces usa la cabecera if-modified-since para madar la fecha al servidor. De esta forma verifica si puede o no la información que tiene cacheada. Si el servidor manda “304 Not Modified” es que puede usarla sin problema.
  • Cabecera expires: Esta mejora todavía más la experiencia del usuario, mientras que la anterior necesitaba validación por parte del servidor para usar los componentes cacheados, mediante la cabecera expires, el servidor indica al navegador la fecha en la que los componentes dejan de ser válidos, por lo tanto, si la fecha de los elementos cacheados es anterior a la fecha de expiración, le indica que puede usar los componetes que tiene en caché sin necesidad de “preguntar” al servidor si pueden o no usarse. Lo cual se traduce en menos peticiones y menor tiempo de carga de la web.
  • keep-alive:  El protocolo HTTP está construido en base al protocolo TCP, en las primeras versiones del protocolo HTTP cada petición necesitaba abrir una conexión y la gestión de todas esas peticiones realizadas sobre una misma web acarreaba un coste en el rendimiento, ya que, un mismo servidor soportaba mútliples peticiones de un mismo servidor, si lo múltiplicamos por múltiples navegadores realizando peticiones, llegamos a la clara conclusión de que el rendimiento se ve afectado. La idea es no tener que gestionar muchas conexiones y usar la misma para multiples conexiones http de un mismo navegador, por lo que se mantiene abierta la conexión entre un navegador y el servidor hasta que se indique mediante la cabecera Connection Close.

Espero que esta primera entrega os haya resultado interesante.