Cómo optimizar la caché del navegador en WordPress

Por , actualizado en

Tabla de contenido

Optimizar la caché de navegador es quizás una de las técnicas de optimización web más incomprendidas; bien usada ofrece resultados impresionantes, y a pesar de eso muchos sitios ni siquiera implementan una política eficiente de caché de navegador, teniendo como resultado un sitio que seguramente no irá muy rápido que digamos. Si has usado GTmetrix u otras herramientas similares y al analizar tu sitio te has encontrado con que tienes una calificación baja en algo que dice Leverage browser cache o algo muy similar, dependiendo de la herramienta: esto se refiere a que tu sitio no está usando esta técnica de optimización que responde al mismo nombre, y que es algo que han ofrecido los navegadores desde hace muchísimos años, aunque de formas cada vez más refinadas hasta llegar a la actualidad. En este tutorial aprenderás qué es la caché del navegador, como controlarla efectivamente, y como determinar una estrategia apropiada de caché para tu sitio.

Pero antes de empezar, una advertencia: este tema es uno de esos que no basta con que copies un bloque de códigos raros, lo pegues y esperes que todo funcione mágicamente; no hay una solución unificada para todos los sitios, y quién te diga lo contrario es un charlatán, así de sencillo. Este tema es uno de esos que tienes que entender para aplicarlo correctamente. La optimización de la caché del navegador puede ser una bendición y una maldición: bien aplicadas puede resultar en ver un sitio web previamente visitado casi instantáneamente; pero si son mal usadas, esos mismos recursos almacenados en caché pueden arruinar la experiencia del usuario al proporcionar contenido obsoleto hace una semana – y probablemente ni lo sepas. Vamos a empezar.

¿Cómo funciona la caché del navegador?

La caché del navegador es un mecanismo muy simple: por cada recurso pedido por el navegador, este verifica si tiene una copia local del mismo y que esté fresca, y de no estarlo, la pide al servidor de origen; de esta manera, se reducen las peticiones que se hacen al servidor y la cantidad de datos transmitidos, sin hacer de lado que el sitio carga mucho más rápido. En la imagen a continuación puedes ver como funciona de manera más gráfica:

Gráfica donde se muestra como funciona la caché del navegador
Cómo funciona la caché del navegador

Como puedes ver, al hacer una primera solicitud de un recurso, si este puede ser almacenado en caché se hace tal cual, y en las próximas peticiones el recurso se toma del caché siempre y cuando este aún sea válido, es decir, no haya cambiado desde la última vez. Ojo, en algunos esquemas de caché no se llega al origen (servidor), lo puse aquí para ejemplificar nada más. Es un mecanismo simple como dije hace un momento, pero funciona de maravilla siempre y cuando se le controle bien, o de lo contrario sólo verás ganancias marginales.

¿Porqué es necesario optimizar la caché del navegador?

En una palabra, desempeño; pocas técnicas tienen un efecto tan radical en el desempeño de tu sitio como optimizar la caché del navegador. Sólo para que se den una idea: de acuerdo con el HTTP Archive, entre los 300,000 sitios principales de acuerdo al rango de Alexa, el navegador puede almacenar en caché casi la mitad de todas las respuestas descargadas, lo que significa un gran ahorro para los que repiten visitas a tu sitio. Esto no significa que ese porcentaje esté grabado en piedra: mientras que otros sitios podrían almacenar en caché hasta más del 90% de sus recursos, otros sitios pueden tener una gran cantidad de datos privados o sensibles al tiempo que no se pueden almacenar en caché.

A nivel técnico, hay dos razones importantes para optimizar la caché del navegador:

  • Reducir la latencia: usando la definición de latencia en Wikipedia, “en redes informáticas de datos la latencia es la suma de retardos temporales dentro de una red. Un retardo es producido por la demora en la propagación y transmisión de paquetes dentro de la red“. En pocas palabras, si hay que dar menos vueltas para mostrar el contenido en pantalla, tu sitio parece más rápido – recuerda que si un contenido particular está cacheado, se sirve desde tu mismo navegador, es decir localmente, contrario a una petición estándar de un recurso a un servidor, que involucra pasos como búsquedas DNS, pings, transferencia, esperas y demás.
  • Reducir el tráfico de red: a pesar de que vivimos en tiempos donde el ancho de banda es “ilimitado” (si, ya sé que no hay tal cosa), aún hay gente que ignora como elegir un servicio de alojamiento de calidad, con servicios que les limitan la transferencia. En estos casos, hay que ver que se transmita lo menos posible, porque te costará. Y si te gastas el ancho de banda…

Tipos de caché

Caché de navegador

Aprovechar la caché del navegador es sobre lo que trataremos en este post; no es más que un espacio en tu disco duro destinado a almacenar elementos de tu sitio que no cambian o que cambiarán poco durante el tiempo. Esta caché tiene un funcionamiento basado en reglas simples, que garanticen que el contenido que estás viendo esté fresco, generalmente una vez por sesión. Es particularmente útil para imágenes en tu sitio que no cambian, las cuales verás que después de una primera visita cargan como rayo a la próxima.

Caché proxy

Los cachés proxy funcionan con el mismo principio pero a escala mayor; los proxies actúan como una puerta de enlace entre el usuario y el servidor de origen, almacenando (o guardando en caché) los recursos del servidor de todos los que se conecten a través de este proxy. Cuando el usuario intenta acceder a un recurso, el proxy verifica si tiene una copia reciente del recurso a la mano. Si es así, el recurso se entrega inmediatamente al usuario. Si no es así, el recurso se recupera del origen y, al mismo tiempo, se guarda en caché en el proxy y se entrega al usuario; de esta manera, si otro usuario solicita el mismo recurso, se toma de este caché.

Caché gateway

Los cachés de puerta de enlace viven como parte de su infraestructura; están frente a tu servidor web y actúan de manera muy similar a los servidores proxy, excepto que son solo para su aplicación (o aplicaciones); también se les conoce como “proxies inversos“.

¿Donde se especifica el control de la caché del navegador?

Hay dos formas de hacerlo: una no es para nada recomendada y como desgraciadamente aún se sigue usando, empezaré mencionándola: en las meta tags de HTML es posible especificar ciertas indicaciones de control de caché, pero no es para nada recomendado precisamente porque forman parte de HTML, y es que se mandan junto con el documento, y no son respetadas por todos los navegadores; los cachés proxy ni siquiera los toman en cuenta; por ello la opción recomendada es controlar la caché usando cabeceras HTTP.

¿Qué es una cabecera HTTP?

Las cabeceras HTTP son instrucciones que se envían antes del contenido HTML, sólo son vistas por el servidor, navegador y cachés intermedios, y que sirven tanto para enviar ciertas indicaciones al servidor y también para recibir respuestas de éste. Hay muchos tipos de cabeceras, las de caché son sólo un grupo de ellas, y son las que nos conciernen aquí.

Estas cabeceras se pueden especificar en varios lugares; si tu servidor web es Apache, lo ideal es especificarlo en el httpd.conf a nivel de definición de host, pero igual lo puedes poner en tu archivo .htaccess. Para nginx hay también un archivo de control por cada sitio, ahí es donde puedes especificar tales cabeceras. Más adelante veremos ejemplos de ambos.

Métodos NO recomendados de control de caché

Dependiendo de cuanto tiempo lleves en este negocio, recordarás las cabeceras pragma; ya están en desuso y son parte de la especificación HTTP/1.0, es decir, son muy viejas. Vamos, muchos CDN’s las ignoran por completo y sólo están ahí para compatibilidad. El modelo de especificar algunas cabeceras de control directo en tags <meta> igual está obsoleto. Si no conoces nada de esto, ¡felicidades! estás sano. Sigamos con esto.

Métodos recomendados para optimizar la caché del navegador

Controlar la caché del navegador va en factor de dos actividades primordiales: controlar la frescura y establecer una forma de validación.

Controlar la frescura con cabeceras HTTP Expires

La manera más simple de controlar la caché es con la cabecera HTTP Expires, la cual indica en que fecha y hora expirará un contenido cacheado; después de ese tiempo, el navegador volverá a revisar el servidor de origen para ver si ya se actualizó el contenido en cuestión. El valor de Expires debe ser un valor de tipo HTTP date (fecha HTTP), que sin meternos a revisar el estándar es una fecha en cierto formato que ahí se especifica. Una cabecera Expires luce así:

Expires: Mon, 01 Dec 2019 16:00:00 GMT

Lo que nos indica que un recurso en particular quedará obsoleto a fines de este año a las 4:00 pm, en el estándar Tiempo Meridiano de Greenwich. El estándar para Expires especifica que cualquier otro valor, incluido el valor cero (0), deberá ser interpretado como en el pasado, y además esto significará que el contenido en cuestión no puede ser almacenado en caché.

Tal cual está en su estándar, la cabecera Expires puede ser útil pero a la vez suele ser problemática; una de las razones es que al ser una fecha fija, si no hay sincronía entre relojes servidor y caché pudieras ver contenido que ya no está fresco; el otro problema viene en que si olvidas cambiar el Expires después del tiempo fijado, el contenido se descargará siempre al terminar este, pues al final del período especificado el tiempo estará en el pasado. Más adelante veremos como mejorar esto gracias a servidores como Apache y nginx.

Control de frescura con cabeceras HTTP Cache-Control

El estándar HTTP 1.1 trajo consigo un nuevo tipo de control de caché de la mano de las cabeceras de respuesta Cache-Control, que se hicieron básicamente para corregir las limitaciones de las cabeceras Expires, y de hecho cuando ambas están presentes, Cache-Control tiene preferencia. La cabecera Cache-Control usa varias directivas para indicar al caché como comportarse. No te preocupes si no los entiendes ahorita, al final lo pondremos todo en práctica:

  • Directivas de cacheabilidad
    • public: significa que cualquier caché puede almacenar este contenido, aun si este no pueda ser almacenado (es decir si no contiene una directiva max-age o Expires).
    • private: Indica que la respuesta está dirigida a un solo usuario (es decir, un navegador) y no debe ser almacenada por un caché compartido o compartido. Un caché privado puede almacenar la respuesta.
    • no-cache: aunque se tenga un recurso en caché, fuerza a que se haga una comprobación al servidor de origen de que dicho recurso no ha cambiado.
    • only-if-cached: Indica no recuperar datos nuevos. Siendo este el caso, el servidor desea que el cliente obtenga una respuesta solo una vez y luego la caché. A partir de este momento, el cliente debe seguir liberando una copia en caché y evitar ponerse en contacto con el servidor de origen para ver si existe una copia más nueva.
  • Directivas de expiración
    • max-age=<segundos>: Especifica la cantidad máxima de tiempo en segundos que un recurso se considerará nuevo. Al contrario de la cabecera Expires, esta directiva es relativa al momento de la solicitud. Los valores comunes que se usan con max-age son:
      • Un minuto: max-age=60
      • Una hora: max-age=3600
      • Un día: max-age=86400
      • Una semana: max-age=604800
      • Un mes: max-age=2628000
      • Un año: max-age=31536000
    • s-maxage=<segundos>: toma precedencia sobre la directiva max-age y la cabecera Expires, pero sólo funciona con caches compartidos.
    • max-stale[=<segundos>]: Indica que el cliente está dispuesto a aceptar una respuesta que haya excedido su tiempo de vencimiento. Opcionalmente, puede asignar un valor en segundos, lo que indica el tiempo en que la respuesta no debe expirar.
    • min-fresh=<segundos>: Indica que el cliente desea una respuesta que todavía estará actualizada durante al menos el número de segundos especificado.
  • Directivas de revalidación y recarga
    • must-revalidate: El caché debe verificar el estado de los recursos obsoletos antes de usarlos y los caducados no deben usarse.
    • proxy-revalidate: Igual que must-revalidate, pero solo se aplica a cachés compartidos (por ejemplo, proxies) y es ignorado por un caché privado.
  • Otros
    • no-store: El caché no debe almacenar nada sobre la solicitud del cliente o la respuesta del servidor.
    • no-transform: esta directiva indica que ningún intermediario puede hacer alguna transformación sobre el contenido.

Notas sobre algunas directivas

El lenguaje elegido para nombrar algunas directivas no es precisamente el mejor: por ejemplo, pensarías que no-cache significa “no almacenes esto en caché“, cuando que en realidad significa que primero debe revisar con el servidor para determinar si el recurso que se tiene almacenado en caché ha cambiado o no. A su vez, no-store significa que no se almacene el recurso en caché; finalmente must-revalidate no significa que deba revalidar el recurso, sino que significa que puede usarse el recurso mientras su edad sea menor que max-age, y cuando no sea así, entonces debe revalidarlo. No golpeen al mensajero…

Validadores de caché

Para determinar si un recurso todavía puede usarse aún cuando su frescura esté en duda, hace falta especificar un validador de caché; gracias a este, puede se evita bajar una copia completa de un recurso del que no se sabe si aún está fresco. Quizás en tus pruebas con GTmetrix u otra herramienta hayas visto que recibes un error llamado “Specify a cache validator“, que es justamente tal cual lo indica. Pero ¿qué es un validador de caché? un validador de caché se define dentro de los encabezados de solicitud y respuesta HTTP y ayuda a determinar si todavía es válido recuperar un archivo del caché del navegador. Los validadores de caché son importantes ya que determinan si se puede usar un recurso directo de caché o bien volver a solicitarlo de nuevo al origen.

Hay dos mecanismos de validación de caché: uno es Last-modified y el otro es el uso de ETags; y esto es importante: si no está disponible ninguno, y no hay información de frescura de/los recurso(s), siempre se sirve el recurso directo del servidor, es decir, no puede haber caché.

El validador Last-Modified

El servidor indica cuando fue la fecha de última modificación del recurso en Last-Modified; de esta manera, al ser entregado por el servidor un navegador almacena en caché el recurso y dicho valor de última modificación; en peticiones subsecuentes, se compara el almacenado en caché y si no difieren se toma el contenido de la caché, aún si este es obsoleto por el tiempo indicado en Cache-Control. Si las fechas no coinciden se envía un código HTTP/1.1 200 y el contenido, y si las fechas coinciden se envía un código HTTP/1.1 304 sin cuerpo, que indica que el recurso aún es válido y que puede tomarse de la caché. Una representación de como funciona el validador Last-Modified va más o menos así (estilo de chat copiado vilmente del excelente post de Jake Archibald sobre el tema):

Simulación de un chat entre el navegador y un servidor web
Simulación de un chat entre un navegador (en azul) y un servidor usando Last-Modified

Sugiero leer de manera complementaria este excelente artículo de KeyCDN sobre los ETags y el código HTTP/1.1 304.

El validador ETags

Con ETags habilitado el servidor retorna un token que puede ser un hash o un tipo de “huella” digital similar para indicar si el contenido está fresco aún; este token se almacena por el navegador, y a la próxima que necesite el mismo recurso compara los tokens, si es igual usa el de caché y si es distinto, lo solicita al servidor. Si el contenido cambia en el servidor, cambia el ETag. Una representación de como funciona el validador ETags va más o menos así:

Simulación de un chat entre el navegador y un servidor web

Simulación de un chat entre un navegador (en azul) y un servidor usando ETags

Sin embargo, los ETags también tienen su problemillas, que tienen que ver directamente con la forma en que se generan. Los ETags tienen tres componentes que son INode (en su sentido más básico, un entero que representa a un archivo), Mtime (fecha de modificación) y Siz (tamaño), pero también pueden generarse con sólo Mtime y Size. El problema viene que este esquema está pensado en sitios que entregan contenido desde un solo servidor; si el contenido está separado a través de varios servidores, entonces el ETag puede dar problemas, por ello muchos blogs recomiendan apagarlo. Regresaremos al tema de los ETag después en este mismo artículo.

Como especificar y controlar la caché del navegador en la práctica

Una advertencia sobre recursos locales y externos

Aún cuando diseñes y ejecutes con éxito una política de caché, recuerda que ésta sólo tiene efecto sobre los recursos que salen de tu servidor. Con esto te quiero decir que todo lo que no venga de tu servidor, como scripts o CSS por incrustar cosas de Facebook, Twitter o las mil porquerías que hay de Google, todo eso tristemente no se cacheará como parte de la política de caché especificada por tu sitio. Ok estoy mintiendo un poco: algunas cosas de Google y quizá una que otra por ahí que olvido en este momento se pueden servir desde tu servidor, pero para la gran mayoría lo que dije es correcto.

Por todo lo anterior es un buena idea decidir si es realmente necesaria en tu sitio cualquier cosa que incida en las peticiones que haga, sea un plugin, algo que incrustes algo o lo que sea que necesite salir de tu servidor para ir a buscarlo a otro. De lo contrario podrías terminar con un recurso que no puedas optimizar al 100%. Para todo lo demás que si se puede optimizar, ¡vamos a ver como hacerlo!

Como usar la cabecera HTTP Expires en Apache

Usa esto para corregir el error de GTmetrix “Leverage browser caching”.

Usando Apache, Expires tiene tres directivas:

  • ExpiresActive: se usa para activar (ExpiresActive on) o desactivar (ExpiresActive off) la generación de cabeceras Expires.
  • ExpiresByType: permite especificar un tiempo en que el recurso estará fresco, especificando el tipo MIME de este.
  • ExpiresDefault: permite especificar un tiempo en que el recurso estará fresco por default para todos los documentos no especificados por ExpiresByType.

ExpiresDefault tiene la sintaxis

ExpiresDefault <code>segundos

Donde <code> puede ser A (tiempo en que se accesó por el cliente) o M (tiempo de última modificación del recurso), y luego segundos equivale a un entero que represente una duración como día, semana, o año (por mencionar algunos) en segundos. La diferencia entre ambos es sutil: usando M cualquier copia en cualquier caché expira al mismo tiempo (piensa en algún contenido que cambie digamos, semanalmente), mientras que usando A el recurso expira en fechas distintas relativas al momento en que haya sido requerido, como por ejemplo imágenes u otros recursos que no cambien seguido. Se usa de la siguiente manera, pensando en ponerlo en el .htaccess:

# habilitar cabeceras Expires
ExpiresActive On

# expirar las imágenes GIF después de un mes en el caché del cliente
ExpiresByType image/gif A2592000

# los documentos HTML son válidos por una semana desde su último cambio
ExpiresByType text/html M604800

No es precisamente intuitivo, ¿no te parece? afortunadamente hay otra manera de hacerlo…

La sintaxis alternativa de las cabeceras Expires en Apache

Afortunadamente Apache nos permite una sintaxis alternativa que hace muy sencillo usar las cabeceras Expires; la sintaxis general es (usando ExpiresDefault):

ExpiresDefault "base[plus num type] [num type] …" 

Donde:

  • base puede ser access (hora de acceso), now (igual a access) o modification. Ojo con modification, pues si se usa sólo se genera si el contenido al que se aplica viene de un archivo almacenado en disco; de lo contrario no se puede calcular la fecha de modificación, y en consecuencia no se genera la cabecera.
  • la palabra plus, pero es opcional.
  • num es un entero.
  • Y por type se puede usar years, months, weeks, days, hours, minutes y seconds.
  • Nota: se pueden usar varios [num type].

Por lo tanto, en el siguiente ejemplo:

ExpiresDefault "access plus 1 month"
ExpiresDefault "access plus 4 weeks"
ExpiresDefault "access plus 30 days" 

Cada línea significa lo mismo: que el tiempo de expiración por default es de 30 días. Veamos como luce con un ExpiresByType, el cual sólo requiere de un parámetro más, que es el tipo MIME antes mencionado (en el siguiente ejemplo es text/html):

ExpiresByType text/html "access plus 1 month 15 days 2 hours"

Aquí tenemos que se está declarando que el contenido de tipo HTML expirará en un mes, quince días y dos horas. Ojo, aquí estamos usando varios intervalos (tres para ser exactos). Como puedes ver, esta sintaxis es mucho más fácil de entender y es la que más te encontrarás en ejemplos.

Cómo usar la cabecera Cache-Control en Apache

Usa esto para corregir el error de GTmetrix “Leverage browser caching”.

La manera más empleada de usar esta cabecera con Apache es como sigue:

<filesMatch ".(jpg|jpeg|png|gif|ico)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>

Aquí estamos estableciendo que todos los archivos con las extensiones que ahí ves tengan un máximo de vida en caché de un año, y que cualquier caché puede almacenar este recurso.

<FilesMatch "\.(js)$">
Header set Cache-Control "max-age=2592000, private"
</FilesMatch>

En este caso, todos los archivos JavaScript pueden ser almacenados en caché por un mes, y sólo en cachés privadas, es decir, del usuario final solamente.

<filesMatch "\.(x?html?|php)$">
Header set Cache-Control "private, no-cache"
</filesMatch>

En este ejemplo podemos ver que todo lo que sea XHTML, HTML y PHP sólo pueden ser almacenados en cachés privadas, y aunque estén en caché hay que revisar con el origen para determinar si han cambiado o no, debido al uso de no-cache.

Cómo arreglar el error “Especificar un validador de caché” (Specify a cache validator)

Usa esto para corregir el error de GTmetrix “Specify a cache validator”.

Como se vio antes, un validador de caché no es más que un mecanismo que ofrece el servidor web para añadirle una huella digital a un recurso, misma que se usa por navegador para determinar si tal recurso se puede usar aún inclusive si no está fresco. Y como también vimos, hay dos: Last-Modified y ETags, que validan por fecha y contenido, respectivamente.

Como controlar el validador de caché Last-Modified en Apache

Con añadir un Expires a tu archivo .htaccess en Apache o bien haciendo lo consecuente con nginx, puedes solucionar este problema. Recuerda que esto sólo se puede hacer sobre los recursos que controlas directamente; si es un recurso que viene de fuera…no hay nada que hacer.

Cómo controlar el validador de caché ETags en Apache

Apache permite configurar la generación de ETags a partir de la directiva FileETag; esta permite indicar que componentes formarán un ETag, de los que hay cuatro disponibles:

  • INode: número de i-nodo del recurso.
  • MTime: fecha y hora de última modificación del recurso.
  • Size: tamaño del recurso en bytes.
  • All: todos los anteriores, equivalente a escribir FileETag INode MTime Size.
  • none: ningún componente.
FileETag INode MTime Size

La orden anterior instruye a que se formen ETags con todos los valores disponibles.


Una discusión breve: ¿se deben usar si o no los ETags?

Geek pensando en optimizar la caché del navegador

Uno de los problemas de usar ETags es que el mecanismo se pensó para recursos que se sirven desde un mismo servidor; cuando se usan varios servidores el mecanismo por default pudiera ser problemático. Por ello, cuando los recursos se sirven desde varios servidores se acostumbra a dejar fuera el INode de los componentes, es decir, se configura así:

FileETag MTime Size

Y con ello brincamos el problema de los múltiples servidores y seguimos usando ETag como mecanismo de validación. Pero eso nos deja con una fecha y un tamaño…eso, argumentan muchos, es casi una cabecera Last-Modified…luego, ¿para que generamos tal ETag? también está el tema de que cuando menos, hace una petición al servidor para comprobar si aún puede usar el recurso, así que en realidad estamos haciendo una petición de apenas unos bytes, pero petición al fin y al cabo; sin embargo, el que uses ETags podría significar que ciertamente se hagan más peticiones, pero que probablemente se descargue menos veces el recurso, y con ETags deshabilitado harás menos peticiones, a costa de que quizás descargues más bytes.

Esto nos lleva a una discusión de que quieras hacer, si quieres ahorrar peticiones (ETags deshabilitado) o ahorrar bytes (ETags habilitado): desafortunadamente esto sólo lo puedes saber analizando tu contenido y tu tráfico, y eso sólo lo sabrás más adelante, no al principio. Para sitios pequeños, de inicio mi recomendación es deshabilitar ETags, y reevaluar más adelante si es necesario implementarlo. Repito, todo esto dependiendo del contenido que tengas y el tráfico que recibas.


Como deshabilitar la generación de ETags

En caso de que no quieras usar ETags, basta con que los desactives usando las siguientes directivas:

# INICIA deshabilitar ETag
Header unset ETag
FileETag None
# FIN deshabilitar ETag

Cómo definir una estrategia de caché eficiente para tu sitio

El camino para elegir una estrategia de caché para un sitio no es necesariamente algo complicado; necesitamos determinar que tipo de contenido tiene nuestro sitio, y cuanto tiempo queremos que esté disponible en caché. Google sugiere este útil diagrama para determinar una política de caché por recurso:

Diagrama para determinar una política de caché apropiada para un recurso
Diagrama para determinar una política de caché apropiada para un recurso

Nota que al final dice “Añadir ETag“, pero como hemos visto, eso queda a tu criterio. Pero regresemos al tema: pensemos en WordPress, un caso concreto, el de este sitio: contiene imágenes (PNG y JPG), archivos de código fuente en (PHP, JavaScript), y HTML y hojas de estilo en cascada (CSS). Vamos a pensar en un solo tipo, digamos las imágenes PNG, y pasémosla por la gráfica de Google:

  • ¿Es reutilizable? Sí
    • ¿Revalidar cada vez? No
      • ¿Cacheable por medios intermedios? Si
        • Máximo tiempo de vida en cache: en mi caso las imágenes una vez que se ponen rara vez cambian, así que iré por el máximo tiempo de vida en caché (el recomendado), es decir, max-age=31536000

Así que en este caso, la directiva quedaría:

Cache-Control public, max-age=31536000

Ahora sólo falta que repliques el proceso para cada tipo de recurso en tu sitio.

TL;DR: Configuración básica para WordPress

Si veniste directo a esta sección, bueno, que lástima. Ojalá que reconsideres y leas lo anterior para que entiendas que pasa. Bien, la intención aquí es proveer un punto de partida para que insertes en tu .htaccess y con esto puedas ir dándole forma conforme al paso del tiempo. Puedes empezar con algo como esto:

## Inicio Expires web caching 
ExpiresActive On
ExpiresByType image/jpg "access 1 year"
ExpiresByType image/jpeg "access 1 year"
ExpiresByType image/gif "access 1 year"
ExpiresByType image/png "access 1 year"
ExpiresByType image/svg "access 1 year"
ExpiresByType text/css "access 1 month"
ExpiresByType application/pdf "access 1 month"
ExpiresByType application/javascript "access 1 month"
ExpiresByType application/x-javascript "access 1 month"
ExpiresByType application/x-shockwave-flash "access 1 month"
ExpiresByType image/x-icon "access 1 year"
ExpiresDefault "access 1 day"
## Final Expires web caching 

# INICIO Cache-Control Headers
<ifModule mod_headers.c>
<filesMatch ".(jpg|jpeg|png|gif|ico)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\.(css)$">
Header set Cache-Control "max-age=2628000, public"
</filesMatch>
<FilesMatch "\.(js)$">
Header set Cache-Control "max-age=2592000, private"
</FilesMatch>
<filesMatch "\.(x?html?|php)$">
Header set Cache-Control "private, no-cache"
</filesMatch>
</ifModule>
# FINAL Cache-Control Headers

# INICIA deshabilitar ETag
Header unset ETag
FileETag None
# FIN deshabilitar ETag

Vuelvo a repetir la advertencia: esto de ninguna manera es una configuración válida para todos los sitios. Es sólo un punto de partida, y te toca a ti medir y hacerle un seguimiento a tu sitio para que aprendas como se desempeña y así poder hacer los cambios necesarios.

Preguntas y respuestas

¿Cuál debo usar, Expires o Cache-Control?

Por supuesto la más nueva, que es Cache-Control; pero es casi una costumbre usar ambas por aquello de algún navegador viejo perdido por ahí.

¿Cómo especifico control de caché para Google Analytics?

Se puede hacer de manera manual, pero para no complicar las cosas puedes instalar el plugin CAOS (Complete Analytics Optimization Suite), el cual descarga una copia de el código de seguimiento de Analytics y lo mantiene actualizado tras bambalinas. Funciona de maravilla.

¿Cómo especifico control de caché para las fuentes de Google?

Del mismo autor del plugin antes mencionado existe CAOS for Webfonts, lo cual hace justo lo que necesitas.

¿Que hago si necesito cambiar un recurso para el cual especifiqué un tiempo de vida de un año en caché?

Lo más recomendado es cambiar el nombre; puedes incluir información semántica de versión, una cadena extra, lo que quieras.

GTmetrix me dice que me faltan varios recursos para optimizar la caché del navegador, ¿que hago?

Historia larga corta, no puedes hacer nada; mientras sean recursos externos, no podrás hacer absolutamente nada. Lo que nos lleva a la conclusión lógica de que debes mantenerlos al mínimo: ¿realmente necesitas mostrar partes de Facebook, Twitter e Instagram (entre otros) en tu sitio? a menos que tengas una razón de peso, sácalos de ahí; son una tonelada de basura que no puedes optimizar.

¿Cómo puedo verificar mi configuración actual de caché de navegador?

Sugiero usar redbot.org.

¡Redbot reporta valores que yo no puse en mi .htaccess! ¿que pasa?

No hay respuesta fácil: tendrás que revisar si alguno de los plugins instalados no interfiere con tu configuración manual. Por ejemplo, WP Super Cache lo hace.

Uso Cloudflare en mi sitio, ¿tengo que hacer algo?

Cloudflare antepone su propia configuración de cache, pero si quieres puedes hacer que respete la original de tu sitio; ve a tu dashboard > Caching > Browser Cache Expiration y selecciona “Respect exisiting headers” del selector. Puede que tengas que esperar un poco a que haga efecto la configuración, o bien puedes purgar toda la caché de Cloudflare para apurarlo.

Palabras finales

Fiu, llegamos al final…espero te sirva la guía y suba tu puntuación en las diversas herramientas que existen, sea GTmetrix, Google, Pingdom, cualquiera, pero recuerda: perseguir un 100% de cumplimiento porque si es perder el tiempo y la sanidad mental. Como siempre, a pesar de que trato de investigar todo muy bien, pueden haber errores y para que el que los comete es muy complicado darse cuenta, así que si detectan uno, por favor no duden en comentármelo para reparalo.

Deja un comentario

Do NOT follow this link or you will be banned from the site!

A %d blogueros les gusta esto: