Як змусити залишити кеш-пам'ять CSS на стороні клієнта?


61

Припустимо, що ми змінили багато функціональних можливостей для модуля (шаблони, макети, CSS) і збираємось перемістити ці зміни на виробничий сайт, але багато клієнтів кешували CSS у своїх браузерах. Тож ось питання. Як змусити залишити кеш-пам'ять клієнта CSS та уникнути перейменування файлів ( styles.css-> styles-v2.css). Є один логічний спосіб, але він не працює в Magento, тому що він перевіряє наявний файл (до речі, цей метод працює для файлів JS), див. Нижче:

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

Будь-які ідеї?

Відповіді:


37

Один із способів вирішення цього питання - це об'єднання CSS. Тоді ви можете просто очистити кеш, і новий об’єднаний файл буде створений з новим ім'ям файлу.

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

Наскільки мені відомо, хеш-код об'єднаного CSS-файлу залишається таким самим, навіть якщо базові файли змінилися - лише якщо нові файли додаються до набору об'єднаних файлів, хеш змінюється. - @Alex

Ще один спосіб вирішення цього питання - замість використання layout.xml,

просто покладіть їх у своє page/html/head.phtml

Або створіть блок, який містить <style>тег з номером версії, і покладіть його в XML в голові, щоб ви могли завантажувати його лише на певні сторінки і все ще дотримуватися використання макетів XML.


10
Наскільки мені відомо, хеш-код об'єднаного CSS-файлу залишається таким самим, навіть якщо базові файли змінилися - лише якщо нові файли додаються до набору об'єднаних файлів, хеш змінюється.
Олексій

@ Алекс цього не знав, має сенс.
Рік Куйперс

4
Я недавно не розглядав це, але раніше компіляція CSS / JS, здається, фактично додає вашому сайту додаткову вагу, якщо ви завантажуєте різні CSS / JS на різні сторінки. Це створило іншу компільовану версію для унікального набору сценаріїв. Це означає, що більші файли, які збираються, по суті завантажуються кілька разів.
Пітер О'Каллаган

@cags - Так, в основному, за цих умов, мінімізація та дозволення завантаження всіх файлів CSS / JS один раз є єдиним підвищенням швидкості.
Лабораторії Фіаско

Іноді це може змінити поведінку CSS, принаймні для мене в Magento 1.9.2.1
Гусь

19

Ви можете використовувати модуль OpenSource Aoe_JsCssTstamp, який додає інформацію про часові позначки до об'єднаних файлів CSS. Тимчасові позначки для простих (не об’єднаних) CSS-файлів ще не підтримуються, проте це було б легко здійснити.


10

Існує безкоштовне розширення на github 'Magento Cachebuster', яке робить саме це. Це повторно

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

Модуль забезпечує кешбестінг, автоматично змінюючи URI, створений Magento для> статичних файлів, додаючи позначку часу до імені файлу:

До: http://www.example.com/js/varien/js.js Після: http://www.example.com/js/varien/js.1324429472.js


2
Цей модуль аналізує HTML для кожної відповіді, щоб додати часові позначки, що може потенційно погіршити продуктивність. github.com/fbrnc/Aoe_JsCssTstamp робить те ж саме більш ефективним способом, але для його виконання потрібно переписати модель пакета дизайну, тоді як Cachebuster використовує лише спостерігач.
Фабіан Шменглер

10

Для цього я використовую власне розширення Speedster Advanced. Але основний принцип полягає в тому, що ім'я об'єднаних файлів css та js включає часову позначку останнього зміненого файлу - див Mage_Core_Model_Design_Package::getMergedCssUrl(). Кожен раз, коли ви редагуєте будь-який із файлів css, створюється нове ім'я файлу, змушуючи браузери запитувати новий файл замість повторного використання кешованої версії. Оскільки ваш головний блок може бути кешований, необхідне оновлення кеш-пам'яті Magento.


Fooman Speedster отримує велике продовження голосування
Bobadevv

8

Я також реалізував кеш-пам'ять для файлів css. Найкращий спосіб, напевно, - це розширити Mage_Page_Block_Html_Head та перейти на функцію нижче та оновити масив $ skinItems з потрібними змінами.

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);

}

Отримав натхнення звідси Джерело


1
Це не буде працювати, файли шкіри завжди будуть повертатися до бази / за замовчуванням, тому що ім'я файлу не буде знайдено в доданій рядку запиту.
BlueC

ваші коментарі "Ім'я файлу не буде знайдено в доданому рядку запиту", що ми хочемо, і це те, що розібне кеш і змусить кеш-сервер отримати нову копію.
Ахад Алі

1
Ні, це зовсім не так. Ви змінюєте значення елементів у масиві $ skinItems, а потім передаєте їх назад до батьківського методу _prepareStaticAndSkinElements (). Цей батьківський метод викличе Mage :: getDesign () -> getSkinUrl () на кожному модифікованому елементі, який буде завжди відновленним до базового / за замовчуванням, оскільки він не може знайти файли з доданим файлом? Fmt = xxx у файловій системі.
BlueC

Не впевнений у його здійсненні, але натхнення, яке з'явилося
Гусак

8

Існує простий, але громіздкий спосіб вирішення, який не вимагає ніяких плагінів і використовує лише вбудовані можливості Magento - корисний, якщо вам просто доведеться швидко зробити це на існуючому сайті, не бажаючи ризикувати встановленням іншого коду.

Ідея полягає в тому, що ви можете використовувати об'єднану систему CSS для створення імені файлу кешу.

Оскільки об'єднаний CSS-файл - це хеш усіх файлів, які об’єднані разом, ви просто додасте додатковий порожній файл css у тему із відбитком дати для імені.

Тому:

  1. Увімкніть об’єднання файлів CSS у меню Конфігурація> Додатково> Розробник
  2. У макеті тем знайдіть, куди ви додаєте CSS-файли в голову (як правило, page.xml) та додаєте додатковий файл таблиці стилів, називайте його все, що завгодно, доки ім'я є унікальним, наприклад <action method="addCss"><stylesheet>css/cachebust_091014.css</stylesheet></action>
  3. У вашій папці CSS шкіри створіть новий файл css з таким ім'ям, для вмісту файлу я просто помістив коментар, у якому йдеться про те, для чого цей файл

Тепер натисніть на цю програму та очистіть кеш-пам'ять magento, файл об'єднаного CSS тепер матиме іншу назву, а ваші кеші будуть розбиті!

Це громіздко, оскільки кожен раз, коли ви хочете розбити кеш, вам потрібно змінити ім'я цього файлу, але він не вимагає нічого, крім вбудованих можливостей Magento, тому це зручно, якщо ви застрягли і потребуєте швидкого виправлення!


7

=> Замість використання цього коду:

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

=> Спробуйте використовувати цей код:

<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>

Але це не дуже приємно ...


Цікава ідея :)
Нік

Це відмінна ідея для короткострокової перевірки.
Джей Ель-Кааке

4

Я знайшов модуль, який додасть рядок запиту до кінця всіх CSS та JS у макетах xml. Рядок запиту може бути налаштований у адміністратора.

https://github.com/mklooss/Loewenstark_Head

Основна ідея - це замінити, _prepareStaticAndSkinElementsщоб включити рядок запиту, як це зроблено в модулі, показаному нижче.

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);
}

3

Якщо я розумію запропоноване рішення у вашому запитанні, ви можете зробити це з невеликим модом до основного файлу ( насправді не редагуйте основний файл ):

Mage / Сторінка / Блок / Html / Head.php

До рядка 198 додайте щось на зразок? V = 1, щоб усі файли css додали це:

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


2

Я створив для цього безкоштовний модуль:

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

Будь ласка, дайте мені знати, якщо це не працює, як очікувалося, але я створив це так, що комбіновані файли js та css матимуть інший хеш, якщо зміст одного з об'єднаних файлів змінився. За замовчуванням Magento змінює хеш комбінованого файлу лише в тому випадку, якщо ім'я одного з включених файлів змінилося.

ОНОВЛЕННЯ

Я також зробив безкоштовний і простий модуль мінімізації для тих, хто вірить у це.

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


Цей модуль не працює ...
SIBHI S

2

Існує дійсно приємний модуль, створений Fabrizio Branca, який робить саме те, що вас цікавить. Він називається AOE_JsCSSTStamp . Що це робить? Це додає часову позначку як CSS, так і JS-ресурсам. Коли ви стираєте кеш CSS / JS, відмітки часу відтворюються.

Веб-переглядач побачить інше ім'я файлу - саме тому він знову завантажить ресурси та подаватиметься найсвіжішим, а не кешований у браузері.


1

Просто відредагуйте метод getCssJsHtml в Mage_Page_Block_Html_Head , додайте такий рядок протягом декількох днів після редагування css, і це все ... це просто працює

// 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
        );

1

Через кілька років, і не знайшовши жодного корисного розширення, яке не об'єднує файли, і це просто, я створив власне. Основна ідея полягає в тому, що після промивання кешу він оновлює Timestamp. Інакше кажучи - коли ви зміните деякі css/js, просто промийте кеш-пам'ять і Timestamp буде оновлено.

Вихідний код тут -> https://github.com/archonkulis/ANSolutions_CssJsTimestamp

Працює на версії 1.9+ . Не впевнений, що стосується старих версій, але, швидше за все, він повинен працювати також.


-2

Створіть копію своєї теми з новою назвою (themev2) - як шкірою, так і додатком / дизайном тощо. Потім виберіть нову тему в адміністраторі.


ні, ти ніколи цього не робиш. це дійсно поганий спосіб зробити це
Маріус

Чому ні? Таким чином, якщо з новою версією щось піде не так, ви можете швидко повернутися до старої. Якщо ви використовуєте довгі часи кешування браузера та / або CDN, щоб обслуговувати свій css (і js, які також можуть бути розмиті / недійсні), це, безумовно, найпростіший спосіб.
Філ Лі

Якщо щось піде не так, ви відкочуєте, який повинен містити інше (старе) ім'я файлу, тому зміна конфігурації (читати як пакунок / тему) не потрібна
Fabian Blechschmidt

Я не знаю, як ви здійснюєте розгортання, але таким чином я повинен зберігати стару папку тем, поки я не зміню значення для пакета / теми або створять сценарій, який оновлює значення при встановленні. Крім того, якщо у мене різні теми, встановлені в різні періоди часу, на них можуть вплинути. Дублювання багатьох файлів - це найпростіший спосіб на сьогоднішній день. Наприклад, встановити це: github.com/jreinke/magento-suffix-static-files набагато простіше. Все, що вам потрібно зробити, - це змінити номер у бекенді після кожного розгортання.
Маріус

Навіть не думай так!
Рінто Джордж
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.