¿Cómo forzar el vaciado de caché CSS en el lado del cliente?

62

Supongamos que cambiamos mucha funcionalidad para el módulo (plantillas, diseños, CSS) y vamos a mover estos cambios al sitio de producción, pero muchos clientes han almacenado en caché CSS en sus navegadores. Entonces aquí hay una pregunta. Cómo forzar el vaciado de la caché CSS del cliente y evitar el cambio de nombre del archivo ( styles.css-> styles-v2.css). Hay una forma lógica, pero no funciona en Magento, porque verifica el archivo existente (por cierto, este método funciona para archivos JS), vea a continuación:

<action method="addCss">
    <stylesheet>css/styles.css?1</stylesheet>
</action>  

¿Algunas ideas?

Mella
fuente

Respuestas:

37

Una forma de lidiar con esto es habilitar la fusión de CSS. Luego, podría borrar el caché y se crearía un nuevo archivo combinado con un nuevo nombre de archivo.

System -> Configuration -> Developer -> CSS settings -> Merge CSS Files

Hasta donde sé, el código hash del archivo CSS combinado permanece igual incluso si los archivos subyacentes cambiaron, solo si se agregan nuevos archivos al conjunto de archivos combinados, el hash cambia. - @Alex

Otra forma de lidiar con esto es en lugar de usar el layout.xml,

solo ponlos en tu page/html/head.phtml

O cree un bloque que contenga una <style>etiqueta con el número de versión y póngalo en el XML en su cabeza para que pueda cargarlo solo en páginas específicas y seguir usando los diseños XML.

Rick Kuipers
fuente
10
Hasta donde sé, el código hash del archivo CSS combinado permanece igual incluso si los archivos subyacentes cambiaron, solo si se agregan nuevos archivos al conjunto de archivos combinados, el hash cambia.
Alex
@Alex no lo sabía, tiene sentido.
Rick Kuipers el
44
No he visto esto recientemente, pero en el pasado la compilación de CSS / JS parece agregar realmente 'peso' adicional a su sitio si carga diferentes CSS / JS en diferentes páginas. Creó una versión compilada diferente por conjunto único de scripts. Esto significa que los archivos más grandes que se compilan esencialmente se descargan varias veces.
Peter O'Callaghan
@cags: Sí, básicamente, en estas condiciones, minimizar y permitir que todos los archivos CSS / JS se descarguen una vez es la única mejora de velocidad que funciona.
Fiasco Labs
Esto a veces puede cambiar el comportamiento de CSS, al menos para mí en Magento 1.9.2.1
Goose
19

Puede usar el módulo OpenSource Aoe_JsCssTstamp que agrega información de marca de tiempo a los archivos CSS combinados. Sin embargo, las marcas de tiempo para archivos CSS simples (no fusionados) aún no son compatibles, pero esto sería fácil de implementar.

Alex
fuente
10

Hay una extensión gratuita en github 'Magento Cachebuster' que hace exactamente esto. Es re

https://github.com/gknoppe-guidance/magento-cachebuster

El módulo proporciona cachebusting al alterar automáticamente el URI creado por Magento para> archivos estáticos al agregar la marca de tiempo del archivo al nombre del archivo:

Antes: http://www.example.com/js/varien/js.js Después: http://www.example.com/js/varien/js.1324429472.js

Kimberely Thomas
fuente
2
Este módulo analiza el HTML de cada respuesta para agregar las marcas de tiempo, lo que podría dañar el rendimiento. github.com/fbrnc/Aoe_JsCssTstamp hace lo mismo de una manera más eficiente , pero necesita reescribir el modelo de paquete de diseño para lograrlo, mientras que Cachebuster solo usa un observador.
Fabian Schmengler
10

Utilizo mi propia extensión Speedster Advanced para esto. Pero el principio básico es que el nombre de los archivos css y js combinados incluye la marca de tiempo del último archivo modificado - vea Mage_Core_Model_Design_Package::getMergedCssUrl(). Cada vez que edita cualquiera de los archivos CSS, se crea un nuevo nombre de archivo, lo que hace que los navegadores soliciten el nuevo archivo en lugar de reutilizar la versión en caché. Como su bloque de cabeza puede estar en caché, se necesita una actualización de caché de Magento.

Kristof en Fooman
fuente
Fooman Speedster obtiene una gran extensión de mi voto
Bobadevv
8

También he implementado un buster de caché para archivos css. Supongo que la mejor manera es extender Mage_Page_Block_Html_Head y anular la función a continuación y actualizar la matriz $ skinItems con los cambios deseados.

protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
{
    $designPackage = Mage::getDesign();
    //$skinItems: contains all css
    foreach ($skinItems as $params => $rows) {
        foreach ($rows as $key=>$name) {
            $file = $designPackage->getFilename($name, array('_type' => 'skin'));
            $skinItems[$params][$key] = $name . "?fmt=" . filemtime($file);
        }
    }
    return parent::_prepareStaticAndSkinElements($format, $staticItems, $skinItems, $mergeCallback);

}

Tengo la inspiración de aquí. Fuente

Ahad Ali
fuente
1
Esto no funcionará, los archivos de máscara siempre volverán a la base / predeterminado porque el nombre de archivo no se encontrará con la cadena de consulta adjunta.
BlueC
sus comentarios "El nombre de archivo no se encontrará con la cadena de consulta adjunta", eso es lo que queremos y eso es lo que destruirá el caché y obligará al servidor de caché a obtener una copia nueva.
Ahad Ali
1
No, así no es como funciona. Cambia los valores de los elementos en la matriz $ skinItems y luego los devuelve al método primario _prepareStaticAndSkinElements (). Este método principal llamará a Mage :: getDesign () -> getSkinUrl () en cada elemento modificado que luego siempre recurrirá a base / default porque no puede ubicar los archivos con el? Fmt = xxx adjunto en el sistema de archivos.
BlueC
No estoy seguro de su implementación, pero la inspiración que se encuentra en la parte inferior definitivamente funciona exactamente como cabría esperar, github.com/mklooss/Loewenstark_Head
Goose
8

Hay una solución simple pero engorrosa que no requiere ningún complemento y solo usa capacidades integradas de Magento, útil si solo tiene que hacerlo rápidamente en un sitio existente sin querer arriesgarse a instalar más código.

La idea es que puede usar el sistema CSS fusionado para generar un nombre de archivo de almacenamiento en caché.

Como el nombre del archivo CSS combinado es un hash de todos los archivos que se combinan, simplemente agregue un archivo css en blanco adicional al tema con una marca de fecha para un nombre.

Entonces:

  1. Active Combinar archivos CSS en Configuración> Avanzado> Desarrollador
  2. En los diseños de tema, encuentre dónde agrega archivos CSS al encabezado (generalmente page.xml) y agrega un archivo de hoja de estilo adicional, llámelo como desee siempre que el nombre sea único, por ejemplo <action method="addCss"><stylesheet>css/cachebust_091014.css</stylesheet></action>
  3. En su carpeta CSS de piel, cree un nuevo archivo CSS con ese nombre, para el contenido del archivo, solo pongo un comentario que dice para qué es el archivo

¡Ahora empuje eso en vivo y vacíe el caché de magento, el archivo css combinado ahora tendrá un nombre diferente y sus cachés serán destruidas!

Es engorroso, ya que cada vez que quieres reventar el caché necesitas cambiar ese nombre de archivo, pero no requiere nada más que las capacidades integradas de Magento, ¡así que es útil si te encuentras atascado y necesitas una solución rápida!

benz001
fuente
7

=> En lugar de usar este código:

<action method="addCss">
    <stylesheet>css/styles.css?1</stylesheet>
</action>

=> Intenta usar este código:

<reference name="head">
    <block type="core/text" name="foocss">
        <action method="setText">
            <css><![CDATA[<link rel="stylesheet" type="text/css" href="foo.css?1" media="all" />]]></css>
        </action>
    </block>
</reference>

Pero no es muy agradable ...

Erfan
fuente
Idea interesante :)
Nick
Esta es una excelente idea para un cheque a corto plazo.
Jay El-Kaake
4

Encontré un módulo que agregará una cadena de consulta al final de todos los CSS y JS en diseños xml. La cadena de consulta es configurable desde el administrador.

https://github.com/mklooss/Loewenstark_Head

La idea básica es anular _prepareStaticAndSkinElementspara incluir una cadena de consulta, como se hizo en el módulo, que se muestra a continuación.

protected function &_prepareStaticAndSkinElements($format, array $staticItems, array $skinItems, $mergeCallback = null)
{
    $version = Mage::getStoreConfig("design/head/meta_version_tag");
    $format = sprintf($format, "%s?v{$version}", "%s");
    return parent::_prepareStaticAndSkinElements($format, $staticItems, $skinItems, $mergeCallback);
}
ganso
fuente
3

Si entiendo la solución propuesta en su pregunta, puede hacerlo con un ligero mod en un archivo central (en realidad no edite el archivo central ):

Mage / Page / Block / Html / Head.php

Agregue algo como? V = 1 a la línea 198 para que todos los archivos css tengan esto adjunto:

$html .= $this->_prepareStaticAndSkinElements('<link rel="stylesheet" type="text/css" href="%s?v=1"%s />' . "\n",
kevando
fuente
2

He creado un módulo gratuito para esto:

http://www.magentocommerce.com/magento-connect/frontend-flush-2048.html

Avíseme si no funciona como se esperaba, pero lo he creado para que los archivos js y css combinados tengan un hash diferente si el contenido de uno de los archivos concatenados ha cambiado. Por defecto, Magento solo cambia el hash del archivo combinado si el nombre de archivo de uno de los archivos incluidos ha cambiado.

ACTUALIZAR

También hice un módulo minify gratuito y simple para aquellos de ustedes que creen en él.

http://www.magentocommerce.com/magento-connect/minify-7771.html

Anton Evers
fuente
Este módulo no funciona ...
SIBHI S
2

Hay un módulo realmente bueno creado por Fabrizio Branca que hace exactamente lo que le interesa. Se llama AOE_JsCSSTStamp . ¿Que hace? Agrega una marca de tiempo a los recursos CSS y JS. Cuando vacías el caché CSS / JS, las marcas de tiempo se recrean.

El navegador verá un nombre de archivo diferente, es por eso que volverá a descargar los recursos nuevamente y se servirá con el más reciente en lugar de almacenarse en caché en el navegador.

versedi
fuente
1

Simplemente edite el método getCssJsHtml en Mage_Page_Block_Html_Head , agregue una cadena como esta durante unos días después de la edición css y eso es todo ... simplemente funciona

// static and skin css
        $html .= $this->_prepareStaticAndSkinElements('<link rel="stylesheet" type="text/css" href="%s?foo=WHAT_YOU_WANT_HERE"%s />' . "\n",
            empty($items['js_css']) ? [] : $items['js_css'],
            empty($items['skin_css']) ? [] : $items['skin_css'],
            $shouldMergeCss ? [Mage::getDesign(), 'getMergedCssUrl'] : null
        );
arno
fuente
1

Pocos años después y al no encontrar ninguna extensión útil que no combine archivos y es simple, creé la mía. La idea principal es que después de vaciar la memoria caché, actualizará la marca de tiempo. En otras palabras, cuando cambie algunos css/js, simplemente vacíe el caché y se actualizará Timestamp.

El código fuente está aquí -> https://github.com/archonkulis/ANSolutions_CssJsTimestamp

Funciona en la versión 1.9+ . Sin embargo, no estoy seguro acerca de las versiones anteriores, pero lo más probable es que también funcione.

usuario3722573
fuente
-2

Haga una copia de su tema con un nuevo nombre (themev2): diseño y aplicación / diseño, etc. Luego elija el nuevo tema en admin.

Phil Lee
fuente
No, nunca haces eso. esa es realmente una mala forma de hacerlo
Marius
Por qué no? De esta manera, si algo sale mal con la nueva versión, puede volver rápidamente a la versión anterior. Si está utilizando largos tiempos de almacenamiento en caché del navegador y / o CDN para servir su css (y js que también podrían necesitar ser vaciados / invalidados), esta es, con mucho, la forma más fácil.
The Phil Lee
Si algo sale mal, retrocede, que debe incluir otro (el antiguo) nombre de archivo, por lo tanto, no es necesario cambiar la configuración (leer como paquete / tema)
Fabian Blechschmidt
No sé cómo se realizan las implementaciones, pero de esta manera tengo que mantener la carpeta del tema anterior hasta que cambie el valor del paquete / tema, o cree un script que actualice el valor en la instalación. Además, si tengo diferentes temas establecidos para diferentes períodos de tiempo, podrían verse afectados. Duplicar muchos archivos es, de lejos, la forma más fácil. Por ejemplo, instalar esto: github.com/jreinke/magento-suffix-static-files es mucho más fácil. Todo lo que tiene que hacer es cambiar un número en el backend después de cada implementación.
Marius
¡Ni siquiera pienses así!
Rinto George