Caché

Última revisión: 28 de diciembre de 2021

Caché

Cuando hablamos de Web Performance un elemento clave tras la optimización de todos los contenidos previos es la de la caché. Un sistema de caché es aquel que permite almacenar elementos ya calculados y repetitivos, pudiendo ser servidos de una forma mucho más rápida que de la habitual.

En WordPress podemos configurar varias capas de caché que harán que nuestro sitio funcione mucho más rápido. Algunas de estas configuraciones son generales del servidor web, otras propias de WordPress, y otras que se pueden mejorar mediante plugins.

Capas de Caché de WordPress

Caché del navegador, caché local o Web App Manifest

Los navegadores web que usamos para visitar los sitios permiten almacenar información que se puede necesitar en varias ocasiones a lo largo de la navegación por el sitio. Por eso es muy probable que la primera visita a un sitio web vaya más lenta, pero posteriormente la velocidad de carga aumente, ya que parte de la información queda almacenada.

Podemos optimizar estos contenidos estáticos directamente desde la configuración de Apache HTTP, nginx o LiteSpeed (o el servidor web que utilices).

Revisa la sección Sistemas de Compresión del Servidor Web.

Caché PHP OPcode

El software del lenguaje de programación PHP, si tiene la extensión correcta, puede habilitar una caché interna que ayuda a la mejora y optimización de código.

Por norma general la caché que viene activa es el OPcache. Puedes ver cómo se activa desde el php.ini.

La caché es interna del PHP, es decir, no tiene nada que ver con WordPress por sí misma, pero sí que afecta el código de WordPress. Al ser propia de PHP, si WordPress actualiza su código (por ejemplo con la actualización de un plugin), el propio PHP por sí mismo no será capaz de saberlo, y por ello necesitaremos un sistema que avise que se ha producido el cambio.

Este sistema es importante por varias razones. La primera es que se cacheará el código fuente de WordPress de forma que sea más rápido de procesar. Un ejemplo fácil es que el código incluye ficheros variados (por ejemplo, en muchos lugares se incluye el código del WP-Config). Estos «includes» quedarán cacheados de forma que en la memoria tendremos ficheros con todo el código completo a ejecutar sin que se tenga que estar incluyendo en cada petición.

Otra de las razones es el funcionamiento de muchos de los plugins de caché de página, que generan contenidos resultantes en PHP y que acabarán sirviéndose como HTML. Este código PHP pre calculado que se genera también pasará a formar parte de la caché de OPcaché, por lo que tendremos código generado y cacheado previamente.

Los plugins, básicamente, lo que hacen es vaciar la caché de PHP correspondiente cuando hay una actualización del código PHP, por ejemplo, con una actualización del núcleo, plugins o temas.

Caché de objetos

WordPress incorpora un sistema interno, que siempre está activo, pero no es permanente, en el que se cachean las peticiones a la base de datos o las que algunos plugins pueden activar en su código.

La caché de objetos es una caché intermedia que principalmente se usa para almacenar resultados de algunas peticiones o contenidos calculados. El uso principal y más habitual es el resultado de las peticiones a la base de datos.

Un ejemplo sencillo y muy fácil de comprender lo tenemos en un sitio en el que en su página principal tenga los 10 últimos contenidos de las entradas. Estos contenidos, mientras algo no cambie (nuevos comentarios, nuevas entradas…) la respuesta de la base de datos siempre será la misma y devolverá los mismos resultados. Aquí es donde entraría esa capa de caché de objetos en la que el resultado de los contenidos que se van a mostrar queda almacenado y se utilizaría hasta que algo no cambie o el contenido caduque. Al no realizar peticiones a la base de datos (lento) sino a la caché (rápido) mejoramos los tiempos de carga.

WordPress incorpora de serie funciones para el uso de dos servicios pensados para optimizar la caché de objetos como son memcached y Redis. Estos son dos servicios que hay que instalar (solo uno de ellos, a elección) en paralelo a lo habitual en WordPress (como son el servidor web o la base de datos).

El funcionamiento de ambos es similar, aunque suelen funcionar de una forma distinta. Por norma general memcached se configura para que el almacenamiento sea en memoria RAM, lo que lo convertiría en un sistema rápido, más caro y que no tiene porqué ser permanente, y Redis sería un sistema que almacenaría la información en disco (por eso se recomienda su uso sobre disco SSD o NVMe) lo que lo hace más barato y permitiría una configuración permanente, de forma que si se reinicia el servicio, podrían quedar almacenados los objetos cacheados previamente.

Este sistema es que no cachea toda la página calculada, sino partes de ella, lo que hace que en páginas que no se pueden cachear por completo, sí que lo hagan ciertas partes que no tienen porqué cambiar.

Plugins para Redis que pueden ser útiles.

Plugins para memcached que pueden ser útiles

Caché de objetos en disco

En caso de no disponer de servidores de almacenamiento externos, se puede utilizar un sistema que utiliza el disco como sistema de almacenamiento de objetos, y lo hace en ficheros PHP, sin necesidad de codificar los contenidos.

En los sistemas Linux, además se puede configurar la memoria como disco, por lo que podemos convertir el espacio en disco donde se almacena la caché en un espacio de memoria. Es importante saber que hay que reservar espacio en memoria RAM, por lo que necesitarás tener este espacio disponible.

cd wp-content/
mount -t tmpfs -o size=512m tmpfs ./cache/docket-cache

En este caso accederemos a la carpeta de wp-content de nuestro WordPress, y allí montaremos un «disco virtual» que en realidad serán 512 MB de memoria RAM.

Caché de página, estática o por PHP

Cuando en general se habla de «activar la caché de WordPress» muchos usuarios se centran en esta capa de caché, la caché de página.

Este sistema de caché básicamente lo que hace es, tras generar el resultado de una página, almacenarla (normalmente en disco) para que, en una siguiente petición, sea más rápida su recuperación.

Existen distintas formas de generar esta caché, siendo las más habituales la recuperación por PHP o la recuperación directa del fichero.

Al igual que en casos anteriores de caché, una de las opciones posibles es almacenar las partes principales de la página, almacenadas de tal forma que, posteriormente con una petición normal y corriente, PHP sea capaz de recuperar esas partes de información y devolver el resultado de la página de una forma rápida.

La otra opción, mucho mejor, sería la de generar una estructura en el disco con todos los contenidos ya calculados, es decir, que tengamos una versión HTML de la página generada en el disco y que, al recibir una petición por parte del servidor web, simplemente se sirva esa versión existente.

Sin duda, en cualquier caso, la segunda opción es la mejor, ya que las peticiones llegan directamente al servidor web que simplemente sirve las páginas ya generadas.

Existen multitud de plugins que se focalizan en este punto, aunque hay otros que añaden otras funcionalidades extra. Como recomendación básica, siempre es mejor tener plugins que hagan cosas concretas y de los que se aproveche la máxima funcionalidad que no plugins muy grandes en los que no se usen la mitad de las funcionalidades.

Caché de página, en servidor web o proxy

La mejor forma de realizar copias de caché suele ser poner un sistema entre el usuario y el servidor web. De esa forma, se solicita la información, se sirve y posteriormente se verifican los cambios o se deja igual hasta que se invalida la información.

Esta capa intermedia puede ser un proxy, habitualmente gestionado por herramientas como nginx (reverse proxy) o Varnish Cache que almacenan una copia de la solicitud y la sirven hasta que el sistema queda invalidado de forma manual o automáticamente cuando llega al tiempo de expiración.

Estos sistemas suelen almacenar una copia en memoria, de forma que se sirve mucho más rápido que de cualquier otro sistema.

Hay que tener en cuenta que este sistema en principio es el óptimo desde el punto de vista de caché, ya que guarda una copia estática de todo el sitio en una capa fuera del propio WordPress y solo se regenera cuando el contenido llega a su fecha de caducidad o el propio WordPress avisa que se ha de regenerar alguna dirección.

En el caso de utilizar Varnish, deberíamos utilizar un plugin que nos ayude a gestionar la actualización de contenidos públicos.

Caché de fragmentos

Este tipo de caché permite disponer de caché por partes dentro del conjunto de una misma página. El sistema más conocido es el ESI (Edge Side Includes) y que, con sistemas externos que lo soporta, permitirían disponer de varias partes cacheadas y fusionar antes de ofrecer al cliente final.

Con este sistema, por ejemplo, una página de una tienda se podría cachear por partes, pudiendo tener una parte común y otras partes separadas, como por ejemplo el carrito que variaría según cada usuario y solo cambiaría si se añade algo en él.

WordPress por defecto no incorpora este sistema, aunque sí que se puede gestionar de forma parcial con sistemas como LiteSpeed Cache o Varnish Cache.

Transient API

Uno de los elementos que lleva funcionando en WordPress desde su versión 3.5 es la Transient API. Estas funciones de WordPress permiten que prácticamente cualquier elemento se almacene en caché sin preocuparnos propiamente de dónde está esa caché.

Con este sistema, cualquier plugin que haga un uso excesivo de consultas a la base de datos puede leer, escribir y procesar información y almacenarla en caché, de forma que en una siguiente petición, ese contenido quede establecido, y la gestión la haga el propio WordPress, por lo que no tenemos que preocuparnos prácticamente de nada.

De esta forma, si eres desarrollador, puedes hacer tu propia consulta a la base de datos, o a una API externa, o al sistema que quieras, y almacenar temporalmente esa información.

set_transient( 'wpsysadmin_resultados_busqueda', $resultado, 6 * HOUR_IN_SECONDS );

En este ejemplo, podemos crear un elemento en la caché llamado wpsysadmin_resultados_busqueda, que tendrá el valor que hayamos añadido en la variable $resultado y que se almacenará durante 6 horas.

Para recuperar la información, podemos lanzar una llamada tal que:

get_transient( 'wpsysadmin_resultados_busqueda' );

Gracias a este sistema, podemos optimizar plugins y otros elementos para que se almacenen en la caché que corresponda, sin que el desarrollador tenga que preocuparse de cuál de ellas.

Redirecciones PHP

Por norma general cuando se hace una redirección no se le indica la duración de esta. Esto significa que tanto los robots como los usuarios, cada vez que visiten la página “antigua” han de hacer la petición porque no se le ha indicado el fin de esta.

En principio el código 301 no debería necesitar de este sistema de indicación de caducidad o caché, pero es recomendable indicarlo ya que no deben ser indefinidas, sino que los 301 hay que eliminarlos pasado un tiempo prudencial (entre 6 meses y un año). Una vez pasado este tiempo esa redirección se debería convertir en un código 404 Not Found.

Un ejemplo en PHP de una redirección correcta podría ser esta:

<?php
header(“Location: https://example.com/”, true, 301);
header(“Expires: Thu, 01 Dec 2021 12:00:00 UTC”);