Los 5 mandamientos de las páginas web rápidas
Por Ricardo Cruz, 10 de Diciembre de 2018. Publicado en Rendimiento. 11 minutos de lectura.Detrás de cada página web hay un sinfín de motivos por los que pueda tardar demasiado en cargar. Este artículo te ayudará a entender las razones y a tomar las decisiones necesarias para corregirlos.
Se reducen a cinco puntos, que se corresponden a los cinco pasos que realiza el navegador a la hora de descargar el HTML de una página web y sus recursos, tales como tipografías, hojas de estilo, imágenes o cualquier otro contenido audiovisual.
- Configura el almacenamiento en la caché del navegador
- Usa un CDN
- Mejora el tiempo de respuesta del servidor
- Reduce el tamaño de los recursos de tu página
- Reduce el uso de JavaScript
1. Configura el almacenamiento en la caché del navegador
La petición más rápida a un servidor web, es aquella que no se hace.
Al introducir una dirección en el navegador, lo primero que hace es buscar, en su almacenamiento interno, una copia reciente de la página que quieres visitar. De ser así, la petición acaba aquí, consiguiendo tiempos de respuesta de entre 0 y 5 milisegundos (la milésima parte de un segundo).
Salvo en casos particulares, como por ejemplo servicios críticos que tengan que mostrar la cotización de la bolsa en tiempo real, el contenido de una página puede almacenarse en la caché del navegador durante minutos, horas o incluso días. En el caso de los recursos asociados a una página, como las hojas de estilo, pueden permanecer muchísimo más tiempo.
Hay dos maneras de hacerlo: Por tiempo o por contenido.
Una caché por tiempo es la opción más sencilla de entender y configurar. Basta con decirle al navegador, mediante una Cabecera HTTP de Respuesta, que el recurso es público y que puede almacenarlo durante la cantidad arbitraria de tiempo que tú quieras.
Piensa en las tipografías especiales que tiene mi página, la primera vez que visitas este artículo, se descargarán junto a la página del HTML, una hoja de estilos CSS y la tipografía que utilizo en los títulos. El contenido de ese fichero con la tipografía nunca lo voy a cambiar, y así se lo he especificado a tu navegador, por lo que la siguiente página de mi sitio web que visites no tendrá que descargarlo de nuevo.
Las imágenes, las hojas de estilo, las tipografías y el JavaScript, salvo necesidades especiales de tu sitio, pueden guardarse durante al menos 15 días en el navegador.
Es tan crucial, o más, planificar y tener bajo control la manera de hacer expirar la caché de un recurso de tu sitio web. Si modificas una zona del HTML de tu página, que depende de un cambio en tus hojas de estilo, hará que se muestre mal, si el navegador no refresca este recurso.
En sitios web sencillos y estáticos, tu servidor web, junto con el navegador de tu visitante, harán todo el trabajo de manera transparente, el navegador hará una petición con una cabecera “If-Modified-Since”. Quiere decir algo como “Necesito que me envíes de nuevo este recurso, si se ha modificado desde la última vez que me lo enviaste”.
Al igual que por tiempo, también se puede generar un identificador único de cada versión del fichero, por ejemplo, mediante el cálculo en MD5 del contenido. El navegador le pedirá al servidor que le envíe el recurso de nuevo en el caso de que el identificador haya cambiado.
En términos de velocidad, el método más eficiente para cachear un recurso (CSS, JS, Tipografías, …), es decirle al navegador que ese fichero no expirará nunca. Si haces cualquier modificación en ese fichero, deberás servirlo bajo otro nombre, por ejemplo, añadiéndole los primeros 6 caracteres del cálculo MD5 del contenido.
En lugar de estilos.css
, por ejemplo, pasaría a llamarse estilos-a1b2c3.css
, cambiando a estilos-b1c2d3.css
al modificarle el contenido.
Este último método requiere algo más de trabajo, ya que las cabeceras del HTML deberán tener calculado el MD5 de la versión más reciente.
2. Usa un CDN
Si el navegador no ha conseguido mostrar una página web utilizando la memoria caché del paso anterior, le hará una petición a tu servidor pidiéndole el contenido.
Cuanto más cerca esté tu servidor de tu usuario, físicamente, menor tiempo de latencia habrá entre el inicio de la petición y el inicio de la descarga, ya que los datos tendrán que viajar menos distancia durante la ida y la vuelta.
Un Content Delivery Network, Content Distribution Network o, en español, Red de Distribución de Contenidos, cumple precisamente con esta función. Se trata de una red de servidores distribuidos a lo largo y ancho del planeta, que guardan copias de los recursos de tu sitio web.
Cuando un usuario le hace una petición a tu sitio web, a través del CDN, éste le envía el fichero que le envíe tu servidor web, guardándose para él mismo una copia en su memoria caché. Si otro usuario le hace la misma petición y el recurso está dentro del tiempo de expiración, se lo enviará desde su servidor sin necesidad de pedírselo de nuevo al tuyo.
Por hacer una analogía, el funcionamiento sería similar al de la distribución de un libro. Pudiendo comprar el mismo libro en Amazon o en tu librería local, lo conseguirías tener en tus manos más rápido comprándoselo al pequeño comercio, siempre y cuando lo tenga en stock (o en la memoria caché del CDN, en nuestro caso).
Para usar correctamente un CDN y que aporte beneficios, previamente tendrás que haber configurado el paso anterior. En caso contrario, simplemente estarás añadiendo un intermediario más entre tu usuario y tu contenido.
Aun sin utilizar su principal característica, que sería mejorar la velocidad de tu web mediante su memoria caché, un CDN aporta beneficios colaterales relacionados con la seguridad, tales como ocultar la IP de tu servidor, o ayudar a mitigar ataques de Denegación de Servicio (DoS).
Algunos CDN populares son Cloudflare o Fastly.
3. Mejora el tiempo de respuesta del servidor
El proceso más rápido es aquel que no se ejecuta.
Si ni la caché del navegador, ni la caché del CDN, han conseguido servir el recurso, será labor de tu servidor preparar y enviar el contenido lo más rápido posible.
¿Pero cuánto tiempo es rápido?. Para hacerte una idea, tu usuario percibirá la carga de tu página web como instantánea si su navegador la reproduce en la pantalla en menos de 80 a 100ms (la décima parte de un segundo). Por encima de ese tiempo, experimentarán diferentes escalas de lentitud y frustración, siendo su paciencia lo único que te salve de perder a un posible seguidor, o cliente.
Ten en cuenta que, aun sin tener que procesar tu servidor nada, en esa minúscula cantidad de tiempo los datos tendrán que recorrer cierta distancia a través de un cable. Todo lo que tarde tu servidor en procesar la petición, será tiempo que se le añadirá a la duración del viaje de vuelta de los datos hasta el navegador del usuario.
En un mundo ideal, en cuanto a velocidad se refiere, las páginas web deberían ser conjuntos de ficheros HTML, CSS e imágenes estáticas. En la mayoría de los casos, salvo aplicaciones web, realmente podría ser así. Sin tratar de convencerte más allá de este párrafo, debería ser tu objetivo.
En la vida real, no siempre es posible. Ya sea por ser un sitio web heredado, limitaciones técnicas, o simplemente porque te apetezca utilizar cierta tecnología, o un gestor de contenidos concreto.
En el caso de sitios web basados en Wordpress, Drupal o Ghost, por poner varios ejemplos, es importante utilizar el sentido común. Todo plugin que sobre, elimínalo. ¿Realmente necesitas un plugin para que el usuario comparta la página en redes sociales?, les basta con copiar y pegar la URL donde les apetezca, y les apetecerá más compartirla si es muy rápida, gracias a quitar esas extensiones que no te sirven para nada.
A la hora de corregir los cuellos de botella que ocurren al procesar peticiones web de tu sitio, es importante no tratar de suponerlo. Si respaldas tus acciones con datos, podrás recortar una mayor cantidad de tiempo con menos esfuerzo, proporcionalmente.
Ya sea combinando herramientas de código libre, como Valgrind, Prometheus y Grafana, como con herramientas comerciales, NewRelic o Datadog, podrás detectar los puntos calientes de tu aplicación que requieran de una atención más urgente.
Indagando en estas herramientas, podrás comprobar si una página concreta de tu sitio web es lenta por estar esperando a una API externa, o porque a una tabla de tu base de datos le falte un índice. Lo importante es que tus decisiones estén respaldadas con datos y no por conjeturas, además de atacar siempre al problema más grave primero.
Y recuerda, una página web lenta propiciará que un atacante pueda colapsar tu servidor con muchísima facilidad.
4. Reduce el tamaño de los recursos de tu página
Incluso si tu sitio web es estático y el tiempo que tarda el servidor en generar las páginas es inexistente, puede que el contenido pese demasiado.
La mejora del ancho de banda en las conexiones a internet de nuestras casas y oficinas, ha propiciado que los desarrolladores web seamos descuidados a la hora de poner a dieta nuestros sitios. Y es un problema grave, porque aunque estas páginas web sean desarrolladas en un ordenador, el uso de dispositivos móviles para acceder a Internet, no deja de crecer.
Una tipografía demasiado grande, una imagen que no se ha redimensionado al tamaño final que va a tener, o sencillamente el uso indiscriminado de JavaScript (que tiene un apartado propio más adelante, en este mismo artículo), harán que la tarifa de datos de tus usuarios crezca, así como la de tu proveedor de hosting.
Si una imagen la vas a mostrar a un tamaño de 400 x 300px, comprueba que no se la estás enviando al usuario a un tamaño de 2000 x 1500px.
Es importante añadir que los servidores web se pueden configurar para comprimir los datos antes de enviarlos al dispositivo de tu usuario, haciendo que los ficheros pesen menos, a cambio de tener que comprimirlos en el servidor y descomprimirlos en el navegador del usuario.
Si tu servidor web es Apache, necesitarás habilitar el módulo mod_deflate
. En el caso de Nginx, basta con activar el soporte para gzip
. En otra ocasión veremos cómo configurarlo en cada caso.
La mayoría de los problemas de este punto se pueden detectar de manera automatizada mediante el uso de servicios online, y destaco PageSpeed Insights, de Google. Una puntuación de 100 sobre 100 en este servicio es el mínimo a lo que debes aspirar, es el equivalente a una página que carga completamente en menos de un segundo.
5. Reduce el uso de JavaScript
Como punto especial en este artículo, está probablemente la tecnología que mayor cantidad de amor y odio está generando en el mundo de las páginas web: JavaScript.
Al igual que ha ocurrido con la mejora de las conexiones a Internet, la mejora en los procesadores de nuestros ordenadores ha hecho que los desarrolladores nos olvidemos de las limitaciones en los dispositivos móviles. Unido a este problema, se ha extendido un mantra universal que trata de convencernos de que JavaScript es rápido, y no lo es.
JavaScript es lento.
JavaScript es lento incluso en su implementación más rápida, y consume más memoria que el lenguaje que más chistes sobre consumo de memoria genera, Java. JavaScript es entre 12 y 64 veces más lento que un lenguaje de programación compilado, en cualquier test de rendimiento que encuentres, quedándose muy atrás incluso frente a algunos lenguajes dinámicos.
Te invito a que pruebes a navegar por tus páginas web favoritas, activando y desactivando JavaScript.
Lejos de tratar de demonizar a JavaScript, te animo a usarlo siempre que lo necesites para resolver algo que no puedas resolver de otra manera. Menús de acordeón, pestañas, popups y muchísimos efectos se ejecutarán con una rapidez más que aceptable, incluso en móviles de gama baja.
El uso de Frameworks pesados, como Angular, React o Vue, deben quedarse relegados a aplicaciones de escritorio, siendo prohibitivos, a nivel de rendimiento, en dispositivos móviles. Si necesitas generar HTML a partir de JavaScript, siempre debes hacerlo en el lado del servidor, nunca en el navegador del usuario.
Navegadores como Chrome o Firefox, ofrecen herramientas para desarrolladores que te permiten encontrar los cuellos de botella de rendimiento, gracias al Profiling. También puedes simular la limitación de las CPU de dispositivos móviles. Aprenderemos cómo en próximos artículos.
Si el uso de JavaScript es fundamental para tu sitio web (de nuevo, porque no vivimos en un mundo ideal), y quieres mejorar la velocidad, o has detectado problemas de rendimiento, puedes hacer uso de Web Workers. Es la única manera de aprovechar en una web varios núcleos del procesador, con JavaScript, ejecutando todo el trabajo pesado en ellos, de una manera independiente al interfaz del usuario.
En general, JavaScript debe entenderse como la sal en la cocina. Un plato sin sal puede resultarte soso, pero si te pasas, lo hará incomestible. Al igual que en la cocina, es muy costoso rectificar un plato (o una página web de cierto tamaño) cuando las pruebas de rendimiento se han dejado para cuando es demasiado tarde.
Conclusión
Una página web rápida no se consigue corrigiendo algo aquí o allá. Como mínimo, será tan lenta como el eslabón más lento de estos cinco pasos:
- Una mala configuración de la caché, obligará al navegador a hacer más peticiones a tu servidor
- La ausencia de un CDN, hará que los datos viajen más kilómetros de cable
- Una tecnología de servidor lenta, afectará al tiempo de respuesta y hará tu sitio web más vulnerable ante ataques de Denegación de Servicio
- El tamaño de los ficheros que envías a tus usuarios afecta especialmente a los visitantes de tu página con conexiones móviles más lentas
- De todos los problemas de rendimiento que puedas tener en tu página web, el más difícil de corregir es un uso indiscriminado de JavaScript
En próximos artículos podrás leer soluciones específicas para solucionar todos estos problemas.