За обновлениями можно следить в telegram-канале https://t.me/quasiart

Тема кеширования в любых системах всегда сложная, поэтому я упростил повествование и опишу типовые ситуации.

Когда человек впервые заходит на сайт, браузер кладёт css- и js-файлы в собственный кеш. Если человек перейдёт на другую страницу, то браузер не будет заново загружать те файлы, что уже есть в кеше. Это отлично экономит нагрузку на сервер, трафик пользователя и, как следствие, скорость работы системы в целом.

Но что делать, если мы произвели некоторые правки в css, а пользователи не видят изменений? Как заставить браузер пользователей загрузить более свежую версию файлов сайта?

Простым вариантом является изменение цифрового отпечатка URL изменённого файла при его подключении.

Допустим, раньше файл подключался так:

<link href="main.css" rel="stylesheet" />

Тогда для того, чтобы все посетители получили новую версию файла, нужно изменить подключение примерно таким образом:

<link href="main.css?v=2" rel="stylesheet" />

Для браузера main.css и main.css?v=2 — это разные ресурсы, хотя фактически ссылаются на один и тот же файл на сервере.

Автоматизация, способ первый

Суть в том, чтобы генерировать уникальный цифровой отпечаток при каждом запросе к странице.

Создаём сниппет и называем его timestamp:

return time();

Подключение:

<link href="main.css?v=[[!time`]]" rel="stylesheet" />

Данный вариант очень простой, но его не рекомендуется использовать в продакшене.  Файл будет каждый раз браться по сети, игнорируя кеш. Я использую этот подход только при активной разработке.

Автоматизация, способ второй

Когда мне надоело каждый раз лезть в чанки и изменять цифровой отпечаток, я решил написать простой плагин, который изменяет цифровой отпечаток только при изменении файлов.

Что нужно сделать:

1. Создать системную настройку assets_version.

Системные настройки MODX

2. Создать плагин с любым названием и привязанным к событию OnFileManagerFileUpdate.

Код плагина:

$basePath = $modx->getOption('base_path');
$debug = false;

// Массив отслеживаемых файлов
$files = [
  'assets/templates/main/css/main.css',
];

switch($modx->event->name) {
  case 'OnFileManagerFileUpdate':    
    foreach ($files as $file) {
      $file = trim($file, '/');
      $filepath = rtrim($basePath, '/').'/'.$file;
      if ($path == $filepath) {
        $setting = $modx->getObject('modSystemSetting', 'assets_version');
        if (is_object($setting)) {
          $setting->set('value', time());
          $setting->save();
          $cacheRefreshOptions = ['system_settings' => []];
          $modx->cacheManager->refresh($cacheRefreshOptions);
        } else {
          if ($debug) {
            $modx->log(xPDO::LOG_LEVEL_ERROR, 'setting not found');
          }
        }
        break;
      }
    }
    break;
}

3. В массиве $files нужно перечислить файлы, изменения в которых будут отслеживаться плагином.

4. Изменить подключение файлов:

<link href="main.css?v=[[!++assets_version]]" rel="stylesheet" />