Cómo activar caché del navegador y compresión en Apache con .htaccess

En servidores Apache, el archivo .htaccess puede utilizarse para definir la caché del navegador y habilitar la compresión de archivos de texto. Estas dos optimizaciones reducen transferencias innecesarias y pueden mejorar el tiempo de carga de un sitio web.

Sin embargo, antes de agregar reglas es importante comprobar si WordPress, un plugin de caché, Cloudflare o el propio servidor ya administran estas funciones. Configuraciones duplicadas pueden producir encabezados contradictorios o dificultar el diagnóstico.

Importante: realizá una copia del archivo .htaccess antes de modificarlo. Un error de sintaxis puede generar un error 500 y dejar temporalmente inaccesible el sitio.

Qué diferencia existe entre caché y compresión

Aunque ambas optimizaciones mejoran el rendimiento, cumplen funciones diferentes.

Caché del navegador

Indica durante cuánto tiempo el navegador puede conservar una copia de archivos como imágenes, hojas de estilo, JavaScript o fuentes. En las siguientes visitas, esos recursos pueden cargarse desde la computadora del usuario sin descargarlos nuevamente.

Compresión

Reduce el tamaño de determinados archivos antes de enviarlos al visitante. Los formatos de texto, como HTML, CSS, JavaScript, JSON, XML y SVG, suelen comprimirse muy bien.

La compresión no almacena el archivo ni reduce la cantidad de solicitudes: disminuye la cantidad de datos transferidos en cada respuesta.

Caché del navegador, caché del servidor y caché de Cloudflare

En un sitio pueden existir varias capas de caché:

  • Caché del navegador: almacena archivos en el dispositivo del visitante.
  • Caché de WordPress: puede guardar páginas ya generadas para reducir el trabajo de PHP y la base de datos.
  • Caché del servidor: puede ser administrada por Apache, LiteSpeed, Nginx u otra tecnología.
  • Caché de Cloudflare: conserva recursos en los centros de datos del CDN.

Las reglas de .htaccess que veremos a continuación controlan principalmente los encabezados enviados desde el servidor de origen. Esos encabezados pueden afectar la caché del navegador y también pueden ser interpretados por Cloudflare cuando el CDN está configurado para respetarlos.

Antes de modificar .htaccess

Realizá estas comprobaciones:

  1. Confirmá que el sitio utilice Apache o un servidor compatible con reglas .htaccess.
  2. Descargá una copia del archivo actual.
  3. Revisá si ya existen bloques de mod_expires o mod_deflate.
  4. Comprobá si un plugin de WordPress administra la caché o la compresión.
  5. Revisá las reglas de caché y compresión configuradas en Cloudflare.

No agregues el mismo bloque varias veces.

Dónde se encuentra el archivo .htaccess

En una instalación habitual dentro de cPanel, el archivo se encuentra en la carpeta principal del sitio. Por ejemplo:

/home/usuario/public_html/.htaccess

El archivo comienza con un punto y puede estar oculto. En el Administrador de archivos de cPanel activá la opción para mostrar archivos ocultos.

Si WordPress está instalado en un subdirectorio o dominio adicional, utilizá el archivo correspondiente a la raíz de esa instalación.

Dónde colocar las reglas

En WordPress conviene agregar las reglas personalizadas antes del bloque generado automáticamente:

# BEGIN WordPress
...
# END WordPress

No modifiques el contenido ubicado entre esos marcadores, porque WordPress o un plugin pueden regenerarlo y eliminar los cambios.

Configurar la caché del navegador con mod_expires

El módulo mod_expires genera los encabezados Expires y el valor max-age de Cache-Control según el tipo de archivo.

Este ejemplo utiliza períodos moderados para evitar que los visitantes conserven durante demasiado tiempo recursos que podrían cambiar:

<IfModule mod_expires.c>
    ExpiresActive On

    # Hojas de estilo y JavaScript
    ExpiresByType text/css "access plus 7 days"
    ExpiresByType text/javascript "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"

    # Imágenes
    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/webp "access plus 1 month"
    ExpiresByType image/avif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 month"

    # Fuentes
    ExpiresByType font/ttf "access plus 1 month"
    ExpiresByType font/otf "access plus 1 month"
    ExpiresByType font/woff "access plus 1 month"
    ExpiresByType font/woff2 "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

    # WebAssembly
    ExpiresByType application/wasm "access plus 1 month"
</IfModule>

La condición IfModule evita que Apache intente ejecutar estas instrucciones cuando mod_expires no está disponible.

Por qué no incluimos HTML en la caché prolongada

El código anterior establece expiraciones solamente para recursos estáticos. No aplica un período prolongado a las páginas HTML.

Cachear HTML indiscriminadamente desde .htaccess puede provocar problemas en:

  • sitios WordPress con usuarios autenticados;
  • carritos de WooCommerce;
  • formularios y áreas privadas;
  • páginas que cambian frecuentemente;
  • contenido personalizado para cada usuario;
  • plugins que ya administran la caché de página.

La caché de HTML debería configurarse desde el plugin, el servidor o Cloudflare, aplicando exclusiones para sesiones, administración, carrito y otras páginas dinámicas.

¿Se pueden utilizar tiempos de caché más largos?

Sí. Los recursos que cambian de nombre cada vez que se actualizan pueden almacenarse durante varios meses o incluso un año.

Por ejemplo, un archivo llamado:

estilos.83ad942.css

puede recibir una expiración prolongada porque una actualización generará un nombre diferente.

En cambio, si el archivo siempre se llama estilos.css, una caché demasiado larga puede hacer que algunos visitantes continúen viendo la versión anterior.

WordPress suele agregar versiones a los recursos mediante parámetros como:

estilos.css?ver=6.8

Antes de utilizar tiempos de un año, verificá que el CMS, tema o proceso de desarrollo cambie correctamente la versión de los archivos.

Activar compresión GZIP con mod_deflate

El módulo mod_deflate comprime la respuesta antes de enviarla al navegador. Se recomienda aplicarlo solamente a formatos basados en texto.

<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/javascript
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/json
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/manifest+json
        AddOutputFilterByType DEFLATE image/svg+xml
    </IfModule>
</IfModule>

Apache agrega automáticamente el encabezado Vary: Accept-Encoding para diferenciar las respuestas comprimidas de las no comprimidas.

Bloque completo listo para .htaccess

Si ninguna otra herramienta administra estas funciones, podés utilizar ambos bloques juntos:

# Caché del navegador para recursos estáticos
<IfModule mod_expires.c>
    ExpiresActive On

    ExpiresByType text/css "access plus 7 days"
    ExpiresByType text/javascript "access plus 7 days"
    ExpiresByType application/javascript "access plus 7 days"

    ExpiresByType image/gif "access plus 1 month"
    ExpiresByType image/jpeg "access plus 1 month"
    ExpiresByType image/png "access plus 1 month"
    ExpiresByType image/webp "access plus 1 month"
    ExpiresByType image/avif "access plus 1 month"
    ExpiresByType image/svg+xml "access plus 1 month"
    ExpiresByType image/x-icon "access plus 1 month"

    ExpiresByType font/ttf "access plus 1 month"
    ExpiresByType font/otf "access plus 1 month"
    ExpiresByType font/woff "access plus 1 month"
    ExpiresByType font/woff2 "access plus 1 month"
    ExpiresByType application/vnd.ms-fontobject "access plus 1 month"

    ExpiresByType application/wasm "access plus 1 month"
</IfModule>

# Compresión para formatos de texto
<IfModule mod_deflate.c>
    <IfModule mod_filter.c>
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/javascript
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/json
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/manifest+json
        AddOutputFilterByType DEFLATE image/svg+xml
    </IfModule>
</IfModule>

Qué archivos no conviene comprimir nuevamente

No es necesario aplicar DEFLATE a formatos que ya utilizan compresión propia:

  • JPEG, PNG, WebP y AVIF;
  • MP3, MP4 y otros formatos multimedia;
  • ZIP, RAR, GZ y archivos similares;
  • PDF;
  • fuentes WOFF y WOFF2.

Intentar comprimirlos nuevamente suele ofrecer una mejora mínima y consume recursos del servidor.

Qué ocurre cuando el sitio utiliza Cloudflare

Cuando Cloudflare está activo con la nube naranja, el visitante se conecta primero con su red. Cloudflare puede entregar archivos utilizando GZIP, Brotli o Zstandard según el navegador, el plan y las reglas configuradas.

Por ese motivo, aunque Apache utilice mod_deflate, el encabezado visible desde el navegador puede ser:

  • Content-Encoding: gzip;
  • Content-Encoding: br;
  • Content-Encoding: zstd;
  • o ninguna compresión si el recurso no corresponde.

Esto no significa necesariamente que la regla de Apache esté mal. Cloudflare puede recibir una respuesta comprimida o sin comprimir desde el origen y elegir el formato que entregará al visitante.

Cloudflare también puede modificar el tiempo de caché

La opción Browser Cache TTL y las Cache Rules pueden modificar el período que recibe el navegador.

Si querés que Cloudflare respete los encabezados configurados en Apache, utilizá la opción correspondiente a respetar los encabezados existentes del origen.

Recordá: purgar la caché de Cloudflare no elimina los archivos que ya están almacenados en el navegador de cada visitante.

Qué ocurre si utilizás un plugin de caché

Plugins como WP Fastest Cache y otras herramientas de optimización pueden escribir sus propias reglas en .htaccess.

Antes de agregar el código manual:

  • revisá si el plugin ya habilitó la caché del navegador;
  • comprobá si ya existe un bloque de compresión;
  • evitá editar secciones identificadas como generadas automáticamente;
  • conservá una copia antes de guardar nuevamente la configuración del plugin.

En WordPress conviene que una sola herramienta sea responsable de cada función. Podés ampliar este tema en nuestra guía para optimizar la caché de WordPress.

Cómo comprobar la caché del navegador

Después de guardar el archivo:

  1. Abrí el sitio en una ventana privada.
  2. Presioná F12 para abrir las herramientas de desarrollo.
  3. Ingresá en la pestaña Red o Network.
  4. Recargá la página.
  5. Seleccioná un archivo CSS, JavaScript o una imagen.
  6. Revisá los encabezados de respuesta.

Deberías encontrar alguno de estos encabezados:

Cache-Control: max-age=604800
Expires: ...

El valor 604800 equivale a siete días. Para los recursos configurados durante un mes, el valor será mayor.

Cómo comprobar la compresión

Seleccioná un archivo HTML, CSS o JavaScript y buscá el encabezado:

Content-Encoding: gzip

Si utilizás Cloudflare, también podrías encontrar:

Content-Encoding: br

o:

Content-Encoding: zstd

El encabezado Vary: Accept-Encoding indica que el servidor o el CDN puede entregar distintas versiones según los formatos admitidos por el navegador.

CF-Cache-Status no indica la caché del navegador

El encabezado CF-Cache-Status informa qué hizo Cloudflare con el recurso:

  • HIT: se entregó desde la caché de Cloudflare.
  • MISS: no estaba almacenado y Cloudflare lo solicitó al origen.
  • DYNAMIC: Cloudflare no lo consideró cacheable con la configuración actual.
  • BYPASS: alguna regla o encabezado indicó que debía evitarse la caché.

Un recurso puede tener caché válida en el navegador aunque CF-Cache-Status no muestre HIT. Son capas diferentes.

Qué hacer si aparece un error 500

Si el sitio deja de funcionar inmediatamente después de editar .htaccess:

  1. restaurá la copia anterior;
  2. comprobá que las etiquetas IfModule estén completas;
  3. revisá si se perdió algún carácter al copiar el código;
  4. eliminá temporalmente el último bloque agregado;
  5. consultá el registro de errores de Apache desde cPanel.

Realizá los cambios de a un bloque por vez. Primero podés probar la caché y después la compresión.

Cuándo .htaccess no tendrá efecto

Las reglas pueden no aplicarse cuando:

  • el sitio utiliza Nginx sin compatibilidad con .htaccess;
  • los módulos de Apache no están habilitados;
  • el proveedor no permite sobrescribir esas directivas;
  • otra configuración del servidor tiene prioridad;
  • Cloudflare reemplaza los encabezados mediante una Cache Rule;
  • un plugin vuelve a escribir el archivo;
  • el recurso se entrega desde otro dominio o CDN.

LiteSpeed suele interpretar reglas compatibles con Apache, pero el comportamiento final puede depender de la configuración del servidor.

Preguntas frecuentes

¿Estas reglas mejoran automáticamente la puntuación de PageSpeed?

Pueden mejorar algunas recomendaciones relacionadas con caché y transferencia de datos, pero el resultado también depende de las imágenes, JavaScript, CSS, fuentes, respuesta del servidor y estructura del sitio.

¿Debo cachear las páginas HTML durante un año?

No de forma general. El HTML puede contener información dinámica, sesiones, formularios o contenido personalizado. La caché de página debe configurarse con exclusiones adecuadas.

¿Puedo utilizar caché de navegador y Cloudflare al mismo tiempo?

Sí. La caché del navegador almacena el recurso en el dispositivo del visitante, mientras que Cloudflare puede conservarlo en su red y evitar solicitudes al servidor de origen.

¿GZIP y Brotli son lo mismo?

No. Son algoritmos de compresión diferentes. Apache mediante mod_deflate entrega habitualmente GZIP, mientras que Cloudflare puede entregar GZIP, Brotli o Zstandard.

¿Debo comprimir imágenes con mod_deflate?

No. JPEG, PNG, WebP y AVIF ya están comprimidos. Conviene optimizar sus dimensiones, formato y calidad en lugar de aplicarles GZIP.

¿Por qué sigo viendo una versión anterior del CSS?

El archivo puede continuar almacenado en el navegador. Cambiá su versión o nombre, limpiá la caché local y revisá también la caché del plugin y de Cloudflare.

¿Necesitás ayuda con .htaccess?

Si tu sitio está alojado en Atlántica Digital, podemos ayudarte a comprobar los módulos disponibles, revisar los encabezados y evitar reglas duplicadas con WordPress o Cloudflare.

También podés consultar nuestra guía específica para activar y comprobar la compresión GZIP.

Abrí un ticket de soporte indicando el dominio y adjuntando el contenido actual de .htaccess, sin incluir contraseñas ni datos privados.