Aportando.es

Velocidad web: teoría, práctica y Escopeta Ferias

Este artículo pretende dar una idea general de lo que podemos hacer para mejorar la velocidad de carga de una web. Y de paso, conoceremos a Escopeta Ferias.


la velocidad importa

¿Es importante la velocidad para el posicionamiento web?

Hay dos motivos principales que parecen indicar que sí:

1)Una mayor velocidad de descarga proporciona una mejor experiencia al usuario. Un buen ejemplo de ello son los miles de euros que deja de ganar Amazon cuando aumenta el tiempo de carga de su página en 0,1 segundos.

2)Los sites lentos o mal optimizados resultan más caros de mantener para los motores de búsqueda como Google, ya que tienen que dedicarles más recursos. Por ejemplo, si todos los sites del mundo disminuyesen su peso total en un 20%, Google ahorraría un porcentaje parecido en discos duros, servidores y ancho de banda.Y al tener menos trabajo las arañas de Google, podrían rastrear los sites con más frecuencia y así ofrecer unas SERP´s de mayor calidad.


Las métricas de velocidad de este post

Este fichero HTML ocupa 51,9KB, consta de 5.213 palabras (31.329 caracteres), utiliza 14 pequeñas imágenes y realiza únicamente 6 peticiones al servidor. Y se descarga totalmente en menos de un segundo (0,7s).

Varias imágenes están combinadas en Sprites CSS, pero la imagen de Escopeta Ferias se carga sola (valga la redundancia).

Escopeta Ferias

Y nuestro amigo Escopeta Ferias, a quien le mola testearlo todo, ha obetnido las siguientes métricas de velocidad web (puedes consultar los informes accendiendo a cada uno de los enlaces):

Google Pagespeed:

El punto que falta es por culpa del tracker de Google Analytics, que no puede ser cacheado porque se encuentra alojado en un hosting diferente al de www.aportando.es.

Pingdom: 794ms, 9 peticiones, 90/100. Más rápido que el 98% de los sitios testeados ahí. En las pruebas que he realizado, el tiempo de carga oscila entre 440ms y 1.340ms.

Webpagetest (testeando desde Francia):

GT Mettrix: Grado de página: A. 0,763s, 6 peticiones, 51,9KB.


El proceso completo de descarga de una página web

Tomando el ejemplo de Google Developers, para que desde un móvil 3G se descargue completamente una página web en un segundo se deberían repartir los tiempos de la siguiente forma:

Con los tres primeros no se puede hacer nada. Pero podemos mejorar los tiempos de los dos últimos si optimizamos nuestro servidor y estructuramos la página correctamente.

En el ejemplo de Google mencionado, entre el tiempo de respuesta del servidor y la renderización del lado del cliente suman 400 milisegundos, pero en la realidad esos tiempos suelen ser muy superiores, al menos el que respecta a la renderización del lado del cliente.


Para facilitar la navegación por el artículo, he creado los marcadores en color azul y los enlaces externos en color naranja oscuro.


Índice

HTML

Javascript

Fuentes de texto

Hojas de estilos (CSS)

Imágenes

Optimizaciones a nivel de servidor

Herramientas de testeo

Fuentes de consulta y enlaces de interés


¡Empezamos!

HTML

Estructura y validación

La estructura del HTML es uno de los factores más importantes para el posicionamiento SEO, y facilitará una carga más rápida de la web.

¿Y qué debería hacer una buena estructura HTML?

Una de las mejores plantillas para crear una web "a mano" es la HTML5 BoilerPlate. Y si usas gestores de contenidos como WordPress, PrestaShop o Magento, puedes buscar en webs como TemplateMonster, pero lo ideal sería comprobar siempre que cumplan las directrices anteriormente mencionadas.

Este documento tiene 6 errores de validación HTML: 3 por cada vez que aparece el icono de Twitter para compartir este artículo, debido a que las URL´s para compartir incluyen el símbolo "&".


Javascript

Métodos de inclusión de scripts

A día de hoy es poco menos que obligatorio usar código Javascript en una página web. Hay tres formas básicas de incluir código Javascript en una web:

Los métodos de inclusión incrustado y en línea no realizan peticiones HTTP al servidor, pero pueden aumentar considerablemente el tamaño de nuestro HTML. Por tanto, pueden ser útiles cuando el código Javascript es pequeño.

Hay que tener en cuenta que la tercera opción es la única que permite cachear los elementos. Por ello, si tenemos archivos Javascript grandes, lo ideal es incluirlos de forma externa (con src="") para que se guarden en la caché de los navegadores.

Colocación

Lo aconsejable, normalmente, es incluir los códigos Javascript en el <footer> de la página. Esto hará que no se carguen ni ejecuten hasta que las líenas que le preceden en el documento HTML no se hayan ejecutado. Si por ejemplo usas Jquery para mostrar/ocultar menús, lo recomendable es colocarlo en el <footer> o justo antes del </body>, porque el usuario cuando visita la página lo que quiere es ver el contenido primero. Luego, si lo considera oportuno, pulsará el botón del menú para mostrarlo u ocultarlo.

En este post, "tó hay que decirlo", únicamente se usa un Javascript externo (analytics.js) y está colocado justo antes del </head>, porque así es como "se conoce" que le mola a Google.

Modos de descarga

Por otro lado, la forma en que se descargan y ejecutan estos scripts también afecta a la velocidad de carga (y a la sensación de velocidad). Vamos a ver los diferentes atributos que podemos especificar dentro del elemento <script> para modificar el método de descarga de los mismos:

Carga normal (<script> sin atributos)

: Parseo HTML

: Parseo pausado

: Descarga de script

: Ejecución de script

Se parsea el HTML hasta que se encuentra un <script>. En ese momento, se detiene el parseo y se procede a realizar una petición para descargar el script (si es externo). El script se ejecutará antes de que se continúe con el parseo HTML.

Carga asíncrona (<script async>)

El script se descargará durante el parseo HTML. Una vez descargado, pausará el parseo para ejecutarse. Cuando termine la ejecución del script continuará el parseo HTML.

Carga aplazada (<script defer>)

La descarga del script se realizará durante el parseo HTML. Cuando finalice el parseo HTML se ejecutarán los scripts que tengan el atributo defer, y lo harán en el mismo orden que aparecen en el HTML.

Se recinuebda usar async siempre que sea posible para la carga de scripts de terceros. En segundo lugar recomienda la carga aplazada, y luego la carga "normal". Hay que tener en cuenta que:

Friendly iFrames

Esta técnica permite ejecutar frames o códigos javascript sin bloquear la descarga del HTML. Originalmente creados por Meebo, los frames amigables son aquellos que están alojados en la mismo dominio en el que se encuentran, y por tanto no necesitan realizar ninguna solicitud externa. Esto puede ser útil para la carga de algunos anuncios, o para cargar el SDK de Facebook, por ejemplo. En este post no he utilizado esta técnica, puesto que el botón de Facebook es un simple enlace hecho a mano.

Scripts de terceros y posibles soluciones

/

Algunos son poco menos que obligatorios, como el tracker de Analytics. Otros, como los usados por los botone de las redes sociales, pueden evitar usarse. Vamos a ver un ejemplo práctico de cuánto se ralentiza la carga de esta página al usar los siguientes scripts de terceros:

Y los que uso de redes sociales:

Total redes sociales: 303KB en 16 solicitudes externas. He probado a quitar los scripts de las redes sociales y la página carga... ¡0,74 segundos antes!

A Escopeta Ferias no le gustan esas cifras. Él quiere ser tan rápida como Gusnanín (Bolt). Por ello ha probado algunos apaños, con diferentes resultados:

Escopeta Ferias

Para compartir en las redes sociales: Image URI + Sprite CSS + URL links:

Si queréis ver un ejemplo en funcionamiento, este post utiliza la combinación de técnicas mencionada para que podáis compartido en las redes sociales. ¡Pruébalo! ;)

Inconvenientes de esta técnica:

Y las ventajas:

Carga de Jquery de forma local

Aunque se recomienda usar siempre la última versión estable de Jquery por temas de actualizaciones de compatibilidad, también puedes copiar el fichero en tu FTP y cargarlo de forma local, ahorrando así una petición externa.

En este post no se utiliza Jquery, pero si lo utilizas en tu web, puedes testear ambos casos y comprobar si en modo local tarda algo menos que solicitando el fichero de forma externa.

Dividir el código de seguimiento de Analytics entre el header y el footer:

Escopeta Ferias lo ha probado pero dice que no sirve "pa ná". Al menos, con el código básico de Analytics no se nota ningún cambio. Aunque separes el código entre el header y el footer, siguen realizando únicamente una petición, tarda los mismos milisegundos en cargar y lo hace de forma asíncrona.

Escopeta Ferias

Carga de las fuentes de texto: preinstaladas, de forma local o desde Google

Básicamente hay tres formas de cargar las fuentes de texto:

Escopeta Ferias ha testeado la carga de fuentes de forma local y desde Google en este post (para la misma fuente, Ubuntu, que ocupa 40KB) y los resultados son un poco contradictorios: al cargarlas desde los servidores de Google, la página tarda 0,4 segundos más en cargar.

Se supone que, por lógica, debería ser más rápido coger las fuentes desde el mismo dominio donde está alojado el docuemnto HTML que hacerlo desde los servidores de Google, pero ocurre al revés. Igual la paralelización de las descargas o la configuración del servidor tienen algo que ver.

Pero repasemos un poco:

En Google Pagespeed las técnicas que obtienen mejor puntuación son la de carga de fuentes preinstaladas y la técnica de @font-face: 5 puntos más que cargando las fuentes desde los servidores de Google.

Y las demás herramientas que uso para testear (Gtmetrix, Pingdom, Webpagetest) dicen que la técnica @font-face es 0,4/0,5 segundos más lenta que las otras dos.

Entonces:

Google Pagespeed está otorgando mejor puntuación a la página que es medio segundo más lenta solo porque descarga las fuentes desde sus servidores (al menos en este caso).

Y la pregunta es:

¿Está Pagespeed en modo "Escopeta Ferias"? ¿O es que Google no quiern que se baje todo el mundo las fuentes de sus servidores? ¿En ese caso, para qué las ponen ahí? ¿Quiénes somos? ¿De dónde venimos?...

Escopeta Ferias

Optimización del código de Javascript y JQuery

Si tu página se basa en Javascript, hay algunas optimizaciones que deberías tener en cuenta, como por ejemplo:

Combinar elementos Javascript

Si tienes varios ficheros Javascript pequeños, puedes acelerar la descarga de tu página uniendo esos ficheros en uno solo, con la consecuente disminución del número de peticiones. Escopeta Ferias nos va a poner un sencillo ejemplo:

Quiere comerse un bocadillo, y para ello necesita pan, aceite y jamón. Y va a tardar menos si pide el bocadillo completo en la panadería que si va primero a la panadería a por el pan, luego a la charcutería a por el jamón y luego a su casa a por el cuchillo.

Pues combinar los JS es como pedir el bocadillo completo en la panadería. Y con los servidores pasa igual: mientras menos los marees, antes acabarán su trabajo.

También hay que tener en cuenta que si usamos varios ficheros Javascript y uno de ellos es muy grande, podemos probar a combinarlos todos menos el más grande, y testear la velocidad de descarga.

Para encontrar la mejor opción deberías realizar pruebas en tu servidor para comprobar si es más rápido realizando dos descargas paralelas o descargando un solo fichero, pero más grande. ¡Testea!


Colocación y carga de CSS, @Import y Link

Vamos a ver las formas básicas de inclusión de CSS en un fichero HTML:

Estructura CSS, Repaints y reflows

Al igual que cuando lo hacemos desde el JS, debemos evitar los repaints y reflows en el CSS. Un ejemplo de repaint es poner el fondo de esta página de color negro, y un ejemplo de relfow es cambiar el ancho de una capa. Procuza minimizar el número de repaints y reflows. O como diría Escopeta Ferias: "no me muevas mucho los divs".

Con la estructura de los estilos pasa lo mismo: cuantas menos líneas uses, menos tardará en cargar y renderizarse. Por ejemplo, si queremos poner todos los <h1> y <h2> en negrita, bastaría con crear una regla para .h1, .h2{} en lugar de crear dos (una para h1 y otra para h2).

<spoiler>

Las formas de inclusión mejor puntuadas por Google PageSpeed son, en este orden:

1) En línea (cuando el código no es muy extenso, como es el caso de este post).

2) Externa: lo normal es incluirlo en el <head> con un <link src>, tal como indican los estándares de la W3C. Pero a Escopeta Ferias le gusta testear. Si lo incluyes justo antes de la etiqueta </body>, obtendrás 5 puntos más en Google PageSpeed que si lo incluyes en el <head> y estarás generando un bonito error en la validación del HTML.

Escopeta Ferias

</spoiler>

Combinar elementos CSS

Al combinar varias hojas de estilos en una sola estaremos reduciendo las peticiones al servidor, tal como ocurre al combinar los Javascripts. Pero si por ejemplo tienes un módulo que usa un fichero CSS de un millón de líneas, lo ideal sería cargarlo con un <link> después de cargar el resto de ficheros CSS.


Imágenes: Escopeta Ferias se arregla para salir

Optimización: formatos, compresión, redimensionado y renderización

Las imágenes pueden (y suelen) lastrar mucho la carga de una web. Para reducir el espacio ocupado en la medida de lo posible, sin que se note visualmente una pérdida de calidad tenemos varias opciones. Pero antes de comprimir una imagen sin pérdida debemos escoger el formato más adecuado. Para simplificar, vamos a reducir la lista a cuatro:

Redimensionado y adaptación de imágenes

Hay que tener en cuenta el tamaño de la imagen y los dispositivos en los cuales se va a visualizar, y debemos especificar la altura y anchura de cada imagen para evitar reflows. No es nada recomendable cambiar el tamaño de las imágenes con CSS porque estaríamos enviando muchos bytes de forma innecesaria.

Por ejemplo, si tienes una imagen de 960 píxeles de ancho:

En un pc de sobremesa ocuparía prácticamente todo el ancho de la pantalla

Si visualizamos la misma imagen desde un IPAD en posición horizontal no habrá problemas (1024px de ancho). Pero si lo colocamos en posición vertical (728 píxeles de ancho), pueden pasar dos cosas: que la imagen no se muestre completamente, o que reduzca de forma automática su tamaño.

Lo mismo pasa cuando visualizamos la página desde un móvil pequeño como el Samsung Galaxy (320 píxeles de ancho).

Una buena opción para solucionar esto sería crear una copia de cada imagen adaptada a cada tipo de dispositvo, y luego cargar la que corresponda vía CSS (responsive images).

Para ello necesitaremos redimensaionar las imágenes. A la hora de hacerlo conviene tener en cuenta que la renderización entrelazada (lanczos) es la que ofrece mayor sensación de velocidad, porque primero muestra una imagen pixelada y la va afinando con nuevas pasadas hasta mostrarla con su aspecto original.

Herramientas hay varias: puedes descargarte algún programa como RIOT (Radical Image Optimization Tool) y acoplarlo mediante un plugin a GIMP, o usar algún otro programa com ImageMagick. También existen plugins muy interesantes para los diferentes gestores de contenidos, como el smush.it para WordPress. Y si no quieres descargar nada ni instalar ningún software, puedes optimizar tus imágenes vía web en alguna página como rsizer.com o TinyPNG (para PNG y JPG).

Data URI

Puedes convertir una imagen en código base64, generando una larga cadena en código ASCII del estilo de "pmLy5+q+Mt2dGaBi14". La técnica data URI consiste enincrustar esa cadena en línea en el código HTML o en el CSS.

La principal ventaja de esta técnica es que ahorraremos peticiones al servidor, y nos puede ser útil cuando tenemos varias imágenes pequeñas. Podéis hacerlo vía web aquí.

Inconvenientes tiene varios:

<spoiler>

No pierdas el tiempo. Tienen un coste muy alto de recursos y mantenimiento para lo poco o nada que aportan.

</spoiler>

Sprites CSS

Esta técnica se basa en combinar diferentes archivos de imágenes en uno solo. A la hora de mostrarlos hay que especificar las coordenadas X e Y en las cuales empieza cada imagen, y el alto y ancho de cada una de ellas.

Ventajas:

Inconvenientes:

En el apartado Javascript > Scripts de terceros podéis ver un ejemplo de uso de sprites CSS para cargar las imágenes de las redes sociales.

Si queréis generar un sprite con varias imágenes podéis hacerlo vía web.


Optimizaciones a nivel de servidor

Hosting compartido, privadom, vps o cloud hosting

Un hosting es básicamente un ordenador con un servidor (Apache) conectado a Internet. Vamos a ver los diferentes tipos de alojamientos:

No siempre es necesario contratar un servidor potente para que la página se descargue de forma veloz. Por ejemplo, si tienes páginas estáticas o si tienes un CMS con poco contenido, te bastará un hosting compartido. Pero si usas páginas dinámicas con mucho contenido, quizás deberías plantearte usar un alojamiento dedicado o un cloud hosting.

Una forma de comprobar si un hosting es rápido es testeando los response times de las diferentes compañías (procurando comprobar si usan CDN´s o no).

Geolocalización Ip, vecinos, ancho de banda y hora de conexión

Si tu página es para españoles, debe estar alojada en España, porque si todas las peticiones se realizan a Jamaica la velocidad de carga se resentirá. Puedes ver cuál es la IP de tu dominio o comprobar en qué geolocalización se aloja.

Si no usas cloud hosting puedes comprobar cuántos vecinos tienes, ya que no es lo mismo compartir recursos con 10 personas que con 150 gamberros. Escopeta Ferias solo tiene 6 vecinos, ¿y tú?

Por otro lado, el ancho de banda del que disponga ese servidor también cuenta, al igual que la hora a la que realicemos las pruebas. No es el mismo testear a las 2 de la mañana que a las 4 de la tarde.

Discos duros SSD

Tengas el tipo de hosting que tengas, lo recomendable es que use discos SSD. Son más rápidos que los tradicionales discos duros rígidos. La memoria de las Solid State Drives (unidades en estado sólido) no está formada por discos, sino que usa semiconductores para almacenar la información.

Las pruebas que ha realizado Escopeta Ferias son claras: los servidores con tecnología SSD cargan entre 2 y 3 veces más rápido las páginas estáticas, y entre 4 y 8 veces más rápido las dinámicas. ¡Casi ná! Aunque eso va a depender en gran parte de la estructura HTML de la página, pero no cabe duda de que los discos SSD son más eficaces.

Configuración de Apache

.htaccess

<spoiler>

Querer realizar grandes cambios en el htaccess de golpe es como pedirle a Eduardo Manostijeras que desactive una bomba.

</spoiler>

Por eso, Escopeta Ferias no va a explicar nada más sobre el htaccess: si no sabes bien lo que es, mejor no lo toques.

Escopeta Ferias

Vamos a ver algunas de las funcionalidades que debería tener un Apache optimizado:

1) Minificación HTML, CSS y JS: esto consiste básicamente en eliminar los espacios que hemos dejado con la barra espaciadora en esos ficheros, siempre y cuando no modifiquen la apariencia de la página. Por ejemplo: este documento HTML, si está minificado, en lugar de empezar así:

Empezaría así:

2) Cacheado de ficheros

Cachear los ficheros consiste guardar una copia de los mismos en la memoria de los navegadores. Cuando el usuario vuelve a visitar una página no necesita descargar esos ficheros de nuevo desde Internet, sino que los descarga de su propio navegador, con la consiguiente ganancia en velocidad.

También hay que tener en cuenta que algunos dispositivos móviles, como el iPhone5, no cachean elementos que pesen más de 25KB.

3) Compresión gzip

Esta funcionalidad, soportada por todos los navegadores, consiste en enviar de forma comprimida los ficheros que se mueven entre el cliente y el servidor, con el consiguiente ahorro de espacio y aumentando de la velocidad de descarga.

Una buena solución es comprimir con gzip todos los archivos menos las imágenes, ya que si las enviamos puede suponer un sobreesfuerzo para el servidor. Las imágenes deben optimizarse para ser comprimidas sin pérdida de calidad, pero no se hace con gzip, sino como hemos descrito antes.

También hay que tener en cuenta otros aspectos, como evitar las redirecciones. Si accedemos a una página que tiene nos redirecciona a otra mediante un 301, la página de destino tardará un poco más en cargar. Lo mismo ocurre si accedemos a esta página a través de un enlace que no lleve las w (http://aportando.es), porque para mostrar la página, primero debe redirigirnos a http://www.aportando.es (que es la versión que he establecido como preferida).

CDN´s: teoría, práctica y Escopeta Ferias

Son las siglas de Content Delivery/Distribution Network (Red de Distribución de Contenidos). Consiste en almacenar copias de los archivos que no necesitan actualización permanente en la caché de múltiples servidores repartidos geográficamente. Su finalidad es la de ofrecer una mayor disponibilidad y velocidad.

Los CDN´s pueden resultar muy beneficiosos cuando son correctamente utilizados. Por ejemplo, para una tienda online con miles de productos podría resultar

Ahora vamos a la práctica:

Un caso de utilización efectiva de loc CDN´s lo tenemos en cubenode.com, una web que ocupa 1.870KB y que realiza nada menos que 87 solicitudes. El tiempo de carga de la primera visita es de 4,596 segundos. Pero a partir de la segunda visita las cifras bajasn de forma drástica: únicamente tiene que cargar 60KB y realizar 10 peticiones al servidor, disminuyendo el tiempo de carga hasta los 2,025s. ¿El "truco"? Sus servidores tienen discos duros SSD y utilizan los CDN´s de Amazon (CloudFront). Esto último podéis comprobarlo pasanándole la araña de las SEO Tools de Excel, por ejemplo.

Escopeta Ferias nunca muere

Y ha observado algo curioso: la página de Amazon CloudFront obtiene pésimas puntuaciones en GooglePagespeed, y también tiene malas métricas en GTMetrix. Lo mismo ocurre con la web de Cubenode que, como he comentado antes, usa los servicios de Amazon CloudFront.

Usar CDN´s bien configurados en una web mal estructurada es como esconder la mierda debajo de la alfombra. Pero si haces buen uso de ellos y además tienes una buena estructura HTML, pordrás ser tan rápido como Gusanín (Bolt).

Aportando no utiliza CDN´s porque, aunque el blog es dinámico, el contenido multimedia del mismo no es demasiado grande. En casos como éste puede resultar contraproducente la utilización de CDN´s.


Herramientas de diagnóstico

Las métricas de velocidad se han comprobado en los siguientes sites:

Google Pagespeed: consejos y puntuaciones para pc, móvil y experiencia de usuario.

GT Metrix: una buena forma de ver el timeline de la descarga de la página.

SEO Tools de Excel: tiempos de respuesta del servidor, detección de CDN´s y más.

Pingdom Tools: tiempos de respuesta, peticiciones realizadas y timeline.

Webpagetest: Permite testear tu web desde múltiples geolocalizaciones (pero no desde España).


Fuentes de consulta y Enlaces de interés

Async vs defer Un gra artículo de growingwiththeweb.com que ha sido de mucha utilidad para la elaboración de este post.

Consejos generales sobre velocidad Recopilación muy interesante de browserdiet.com/es/

CDN según Wikipedia.

CSS W3C Cómo colocar el cSS.

Friendly iFrames Para el SDK de Facebook.


¿Qué cambiarías o añadirías? ¿Te ha gustado el artículo? Puedes contármelo por correo o por las redes sociales. ¡Prometo contestar!