Cache navegador y WordPress
-
Hace ya un tiempo, nuestro compañero @fernandot escribió un artículo donde explicaba como solucionar los errores de Leverage Browser Caching mediante «Cache-Control» o «Expires Headers».
Lo tenía todo claro hasta que leí el siguiente artículo: https://cybmeta.com/no-utilices-cache-de-navegador-para-html
Si no lo he entendido mal, sería preferible sustituir «Cache-Control» o «Expires Headers» con el código que se indica en el artículo de @cybmeta
¿Podéis aclarar el asunto? Gracias.
- Este debate fue modificado hace 5 años, 1 mes por almendron.
-
En mi artículo expongo una situación específica en la que yo prefiero que el navegador no cachee documentos HTML y otros documentos similares que se pueden considerar dinámicos, es mi caso concreto y no creo que sea para todas las situaciones.
De todas formas, los errores de Leverage Browser Caching suelen aplicarse solo a componentes estáticos (css, js, imágenes, vídeos, etc). Para ese tipo de recursos sí que es recomendable especificar una caché de navegador siempre, y si no la pones te saldrá ese error en la mayoría de herramientas de test de velocidad. Pero en mi artículo no trato esto.
Espero haberme explicado bien.
En realidad, mi pregunta tampoco está directamente relacionada con el error Leverage Browser Caching.
Voy más encaminado a entender si es preferible utilizar tu perspectiva o bien usar «Cache-Control» o «Expires Headers» para mejorar la experiencia de navegación de las personas que visitan mi blog.
En mi caso al menos, una gran mayoría de visitantes repiten casi todos los días.
Para recursos que son realmente estáticos sí, siempre hay que poner una caché de navegador con cache-control o expires (yo prefiero cache-control), y con un tiempo realmente largo, tipo un año (31536000 segundos, que es el máximo que se puede poner).
Para el HTML y otros recursos dinámicos (esto es lo que trato en el artículo) pues depende de lo que quieras. La opción más agresiva es nada de cache. Pero si tus posts no se actualizan mucho o no contienen información que tenga que ser actualizada al instante, puedes poner una cache pequeña o moderada, tipo media hora, una hora, o algo así.
Por ejemplo, la portada de tu blog es HTML. Si pones un tiempo de caché de un año, un usuario que visite la portada del blog no verá la portada con los nuevos posts que escribas hasta que no pase un año. Por eso digo que para el HTML hay que tener cuidado con la cache y ser moderado, y el mejor tiempo de caché depende de cada caso.
A ver si lo he entendido. Mi caso es un blog tradicional en el que los artículos se modifican en pocas ocasiones pero la página principal, páginas de archivos como categorías o etiquetas cambian cada vez que inserto un nuevo artículo.
Por otro lado, otros recursos como imágenes o PDF,s no suelen cambiarse.Por tanto, podría poner lo siguiente:
1) Para recursos estáticos:
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"> Header set Cache-Control "max-age=86400, public" </filesMatch>
2) Para HTML:
<FilesMatch "\.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|HTML|HTM|RTF|RTX|SVG|SVGZ|TXT|XSD|XSL|XML)$"> FileETag MTime Size <IfModule mod_headers.c> Header set Cache-Control "no-cache" Header unset Last-Modified </IfModule> </FilesMatch>
¿Estaría bien así?
Exacto. Eso es. Aunque yo para recursos estáticos pondría el máximo de caché (un año) porque no cambian nunca. Si un archivo css, js, imagen, etc, se cambia la URL/nombre del archivo, así que no hay problema con poner el máximo de caché.
<filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf)$"> Header set Cache-Control "max-age=31536000, public" </filesMatch>
Y para el HTML, como norma general no-cache, pero luego se puede tunear para cada caso. Por ejemplo, yo en la mayoría de blogs normales y corrientes pongo una cache de 30 minutos (desde WordPress, no desde .htaccess para distinguir entre usuarios logeados y no):
add_action( 'send_headers', 'cyb_cache_headers', 0 ); function cyb_cache_headers() { if( is_user_logged_in() ) { // nada de caché ni el navegador ni proxys intermedios $cache_policy = "no-cache,no-store,max-age=0,s-maxage=0,private"; } else { // Guardar en caché durante 30 minutos y // durante 1 hora después servir las copias viejas // mientras se renueva la caché $cache_policy = "max-age=1800, stale-if-error=3600, stale-while-revalidate=3600, public"; } header( 'Cache-Control: ' . $cache_policy ); }
Pero eso ya a gusto del consumidor.
Hasta ahora, yo usaba «Expires headers» con distintos tiempos. Para el HTMl usaba
ExpiresByType text/html "access plus 0 seconds"
por lo que entiendo que la página nunca se almacenaba en el cache del navegador del cliente.Tras leer tus explicaciones, he decidido que, de momento, paso a «Cache-Control» para los contenidos estáticos y los «ETags» para el HTML. En este último caso, entiendo que ahora sí que se almacenará en la cache del navegador del visitante pero se le volverá a servir en caso de cambiar la página.
La función que expones es muy interesante. La aplicaré más adelante. Ahora de momento, quiero ver las páginas como si fuera un visitante más.
Solo me quedan dos dudas:
1) He añadido a los recursos estáticos las extensiones «mp3» y «mp4». ¿Es correcto?
2) ¿Cómo puedo comprobar que el código funciona? ¿Alguna herramienta para analizar las cabeceras?
Y dejo el código que voy a dejar de momento:
<IfModule mod_headers.c> <filesMatch ".(ico|pdf|flv|jpg|jpeg|png|gif|js|css|mp3|mp4|swf)$"> Header set Cache-Control "max-age=604800, public" </filesMatch> </IfModule> <FilesMatch "\.(html|htm|rtf|rtx|svg|svgz|txt|xsd|xsl|xml|HTML|HTM|RTF|RTX|SVG|SVGZ|TXT|XSD|XSL|XML)$"> FileETag MTime Size <IfModule mod_headers.c> Header set Cache-Control "no-cache" Header unset Last-Modified </IfModule> </FilesMatch>
mp3 y mp4 son estáticos, así que sí, es correcto.
Para comprobar que funciona puedes utilizar las herramientas de desarrollo del navegador, en la sección «Network» o «Red».
Muchísimas gracias por todo, @cybmeta
Creo que podemos dar por resuelto el hilo. Espero que lo aquí explicado sirva a más personas.
- El debate ‘Cache navegador y WordPress’ está cerrado a nuevas respuestas.