¿Cómo acelerar tus plataformas web?

Cuando desarrollamos plataformas no siempre pensamos en la velocidad y casi siempre es muy tarde para reprogramar todo de la manera correcta, por ello te doy algunos consejos de infraestructura la mayoría que pueden apoyarte y se basan enteramente en mi experiencia:

Cambiar a Nginx

Nginx es un servidor web que puede ser utilizado también como proxy de alto rendimiento, es de software libre y de código abierto, licenciado bajo la Licencia BSD simplificada; también existe una versión comercial distribuida bajo el nombre de nginx plus.

Nginx es multiplataforma, por lo que corre en sistemas tipo Unix (GNU/Linux, BSD, Solaris, Mac OS X, etc.) y Windows.

Es una alternativa al servidor Apache y la razón principal de su popularidad es muy obvia, es un servidor muy rápido, el cual puede soportar alto tráfico, puede utilizar PHP en modalidad PHP-FPM (FastCGI Process Manager).

Algo que tienes que considerar es que si decides hacer uso de Nginx, es que si actualmente usas Apache, la sintaxis de los .htaccess cambian  por lo que tendrás que modificarlo y cambiar la sintaxis para que tu sitio/sistema web funcionen correctamente.

Una manera o truco para los que les sea muy complicado realizar esto, o no desean arriesgarse, es utilizar Nginx como reverse proxy, siendo intermediario entre el servidor (que puede ser apache, IIS etc..) y el usuario, de tal forma que nginx cacheará todo el contenido y la respuesta será más rápida, de esta manera no tendrás que alterar tu servidor actual.

https://www.nginx.com


Utilizar memcached o Redis

Implementa un motor de base de datos basado en memoria, puede ser memcached, Redis o mongo. La memoria RAM es mucho más rápida en lectura-escritura que la ROM.

Yo utilizo memcached y me ha funcionado bastante bien, pero ¿qué puedes almacenar en memoria? absolutamente todo, strings, objetos, arreglos.

En mi caso suelo almacenar la información de los resultados de consultas a mis base de datos que suelen ser repetitivas, como catálogos búsquedas entre otros, de tal manera que la próxima ves que se ejecute la misma consulta, solo tengo que recurrir a los datos cacheados en memcached y así no consumiré recursos en conectarmerme a la bdd y ejecutar la consulta.

La instalación es sumamente sencilla y PHP cuenta con una extensión el cual puedes instalar con PECL con el cual podrás hacer uso de las funciones y métodos de manera nativa.

En caso que no puedas realizar la instalación de la extensión hay liberías que puedes utlizar como «Memcached Client»:
https://github.com/fwolf/memcached-client

Su uso es tan sencillo como:

<?php
//Conecta
$m = new Memcached();
$m->addServer('localhost', 11211);
//Almacena
$m->set('identificador', 'una cadena sencilla');
//Obtiene
echo $m->get('identificador');
?>

 

MySQL recomienda su uso y hay documentación oficial al respecto, de como usar MemCached + (PHP,C,C++,Perl, Phyton, Ruby y JAVA) + MySQL:
https://dev.mysql.com/doc/refman/5.6/en/ha-memcached-interfaces.html


Utilizar un CDN

Utiliza un CDN (content delivery network) para tus recursos estáticos. ¿Qué es un CDN? un CDN es una red de entrega de contenidos en el cual cualquier archivo que almacenes en un contenedor, será replicado en los diversos PoP (puntos de presencia) a escala mundial, de tal manera que cuando un usuario ingrese a tu sitio o sistema y su navegador invoque por ejemplo a: «template.css», el CDN determinará cual PoP es el más cercano al usuario para responder la petición desde ahí, esto minimiza el tiempo de respuesta y ahorra recursos de procesamiento a tu servidor.

Las ventajas son simples: mayor velocidad de respuesta, ahorro de recursos de procesamiento, memoria y ancho de banda.

Existen muchos CDN la gran mayoría son de paga y cobran por el ancho de banda que transfieran, en lo personal yo uso CloudFiles de Rackspace y lo utilizo por ejemplo para este blog, en el cual se almaceno las imágenes:

Ejemplo:
https://484c2a6d15c399b70beb-b1e2a15a3df201703b71bb9b31acda05.ssl.cf5.rackcdn.com/2017/07/reverseproxy-1024×217.png

Cloudfiles de Rackspace tiene soporte de Alias CNAME, por tanto la URL anterior puede ser invocada de la siguiente manera:

http://cdn.puchunguis.com/2017/07/reverseproxy-1024×217.png

Yo te recomiendo cachear todo tipo de contenidos estáticos, como: archivos css, js, imágenes y fuentes.

Existen muchas alternativas, como Microsoft Azure File Storage, Amazon S3, Akamai y muchos más, tendrás que evaluar cual es el que más te conviene.

Si deseas una alternativa gratuita puedes usar CloudFlare, al instalarlo automáticamente implementa la función CDN en tu sitio, pero no tendrás control de éste, ya que CloudFlare decidirá que cachea y que no.


Utiliza AMP

Antes teníamos WML, luego salieron las páginas responsivas, pero ahora tenemos a AMP.

El proyecto AMP es muy simple, es una iniciativa de código abierto que busca mejorar el rendimiento de las páginas haciendo que los sitios web y anuncios sean consistentemente rápidos y de alto rendimiento en dispositivos y plataformas de distribución móvil.

Funciona controlando la renderización de los elementos bajo demanda, quitándole al navegador el control, de tal forma que los elementos web los cargará cuando el usuario los necesite, de esta manera la carga es mucho mas rápida.

Por lo que te sugiero realizar una versión móvil especial para tu sitio en versión AMP, siempre y cuando esto sea viable, ya que este framework tiene algunas limitantes entre ellas el uso avanzado de javascript.

https://www.ampproject.org/es/


Comprime el contenido de los recursos estáticos

El tamaño si importa, digan lo que digan. Mientras más grande sea un archivo más tiempo le tomará a tu servidor procesarlo y transferirlo, por tanto es vital que tus recursos sean lo más ligeros posibles, entonces ¿qué podemos hacer para aligerarlos?

  • Comprime las imágenes: Comprime todas las imágenes de tu sitio esto reducirá el peso de tu web hasta en un 50%, hay herramientas como RIOT (Radical Image Optimization Tool) que te pueden ayudar hacer esto.
  • Comprime el contenido HTML, CSS y JS: El código fuente contiene strings que generalmente olvidamos, como: saltos de página o espacios de más, éstas cadenas que no forman parte de la funcionalidad y solo ocupan espacio, por tanto mientras más pequeño sea el código fuente más rápido podrá ser transferido.
    Existen herramientas que puedes usar como: Minify, JS Compress, HTML Compressor y CSS Compressor.

Comprime la transferencia con Gzip

Habilita la compresión GZIP. Esta opción se realiza en la configuración del servidor Apache, IIS…etc, existe la forma de realizarlo directamente por código fuente, sin embargo no te recomiendo esto ya que el consumo de procesador aumentará un poco.

La compresión por GZIP genera un mejor desempeño en la carga de las páginas, ya que consiste en comprimir todo el contenido que servidor transfiere para que este ocupe mucho menos espacio y por tanto se transfiera por la Red de forma más rápida, el navegador del cliente identifica por medio de una cabecera que el contenido que está recibiendo se encuentra comprimido (Content-Encoding:gzip) y automáticamente lo descomprime.

Para el usuario es totalmente transparente.


Habilita HTTP2 ó SPDY

Instala, configura y habilita HTTP2, SPDY era una buena opción pero actualmente se encuentra obsoleto.

Con HTTP/1.1 (actualmente) Cuando visitas esta página o sistema web, tu navegador realiza muchas peticiones a diversos recursos, como : imágenes, css y archivos js entre otros; cada recurso genera un socket de conexión entre tu navegador y el servidor web, por el cual se transfiere la información.

Con HTTP2 se cambia este esquema, de tal forma que con una sola conexión se pueda transferir más de un solo recurso, aumentando la velocidad de respuesta y ahorrando procesamiento y ancho de banda.

La configuración no es tan sencilla pero las ventajas son muchas y puedes reducir el TTFB hasta en un 50%, para cada servidor se hace de forma distinta por lo que no hay una «guía estandar» pero podrás hacer tus pruebas con la herramienta: https://tools.keycdn.com/http2-test.


Aumenta la cache expiration de los headers

Cuando nuestro navegador visita una página o sistema web, descarga el código fuente así como los recursos.

Cada recurso se «cachea» de tal manera que al navegar dentro del sitio, no se vuelven a descargar los que ya se han descargado con anterioridad, ahorrando ancho de banda, procesador y memoria. El navegador se vale de un header para determinar cuando sincronizar o descargar de nuevo los recursos, este header es Expires ejemplo:

Expires: Wed, 11 Jan 2017 05:00:00 GMT

Este header indica la fecha (en formato de tiemp RFC 1123) en la cual expirará el recurso y deberá sincronizarse de nuevo.

Una forma de hacerlo de forma sencilla es con un .htaccess por ejemplo:

<IfModule mod_expires.c>
ExpiresActive on

# Perhaps better to whitelist expires rules? Perhaps.
ExpiresDefault "access plus 1 month"

# Data
ExpiresByType text/xml "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType application/json "access plus 0 seconds"

# Favicon (cannot be renamed)
ExpiresByType image/x-icon "access plus 1 week"

# Media: images, video, audio
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"

# Webfonts
ExpiresByType application/x-font-ttf "access plus 1 month"
ExpiresByType font/opentype "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

# CSS and JavaScript
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"

</IfModule>

Modifica la configuración de MySQL

MySQL tiene parámetros de configuración que a veces ignoramos, ya que dejamos la configuración que trae por default. Algunos de estos parámetros dependen de las características físicas y la versión de MySQL que tengas, pero te comparto algunas de ellas:

Habilita los hilos:

  • thread_concurrency = 8
  • thread_cache_size

Se sugiere que el número de hilos sea el doble de CPU’s que tengas disponible.

Modifica el tamaño de los buffers:

  • key_buffer_size
  • sort_buffer_size
  • read_buffer_size
  • read_rnd_buffer_size
  • myisam_sort_buffer_size

Habilita el cache de MySQL:

  • query_cache_type
  • query_cache_size
  • table_open_cache

Manejo de sesiones y conexiones:

  • max_connections
  • interactive_timeout
  • wait_timeout
  • connect_timeout

Estos parámetros son los que considero de gran valía y te ayudarán a incrementar el rendimiendo de MySQL, sin embargo existen otros, la documentación oficial de MySQL tiene mucha ayuda al respecto y podrás consultarla aquí: https://dev.mysql.com/doc/refman/5.6/en/performance-schema.html


Cambiar gestión de sesiones de PHP

La memoria es más rápida para acceder a la información que almacena en comparación que un disco duro. Por default si usas PHP, este maneja las sesiones generando archivos en el disco duro, el folder casi siempre es la carpeta tmp, a reserva que hayas modificado el valor session.save_path.

Por cada sesión generará un archivo y si tu servidor es de alto tráfico, estos podrían ser varios cientos de miles, llegando a un punto donde el servidor se alentará naturalmente.

Existe una manera de acelerar la gestión de sesiones por medio de Memcached, en la cual ya no se escribirán más archivos de sesión y en cambio se guardarán directamente en memoria.

Basta con instalar el servidor memcached, la extensión para PHP por medio de PECL y posteriormente editar el PHP ini de la siguiente manera:

Ubica el valor session.save_handler y remplázalo con:

session.save_handler = memcached
session.save_path = «localhost:11211»

Posteriormente reinicia tu servidor web y con esto las sesiones se gestionarán a través de Memcached.


Utiliza Sprites para las imágenes

Imagina que vas a la tienda a comprar 10 artículos. ¿Qué sería más tardado? poner los 10 artículos en 10 carritos distintos y pagar uno por uno cada artículo de manera independiente ó naturalmente poner los 10 artículos en un solo carrito y pagarlos todos en una sola compra.

Pues es exactamente lo mismo para los servidores, es más tardado bajar 10 imágenes (por ejemplo iconos) de manera independiente, que bajar una sola imagen que incluya todos los iconos.

Ya que al bajar una imagen se dispara todo el ciclo de vida del servidor, por ejemplo en apache para cada request que se sirve, se tiene que pasar por esto:

  • Generación de Request
  • Lectura POST-GET
  • Traducción de la URI
  • Parseo de los headers
  • Control de Acceso
  • Verificación de autenticación
  • Autorización
  • Verificación de MIME type
  • Creación de Fixups
  • Respuesta
  • Limpieza

Todo esto utilizando Logging y sin contar el propio ciclo de vida de PHP y la plataforma que aloja.

Es por esto que mientras menos request realice nuestra plataforma es mejor, para esto se utiliza un truco se CSS llamado sprites, con el cual se integran un conjunto de imágenes en una sola y se imprimen por medio de CSS estableciendo sus dimensiones, por ejemplo:

Iconos en Sprite

Al mostrarlas por css solo mostraremos el adecuado.

En internet encontrarás muchos ejemplos al respecto.

Con esto llegamos al fin de mis consejos, espero te sirvan de ayuda y se mejore la velocidad de tus plataformas web.

 

Leave a Reply

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.