Артефакты MinifyX при его вызове через runSnippet

MinifyX можно использовать двумя способами:

Вариант 1. Как обычно:
[[!MinifyX? &cssSources=`/css/st.css` &minifyCss = `1` &forceUpdate = `0`
            ®isterCss = `placeholder`
            &cacheFolder=`css/min/` &cssFilename = `css1`]]
[[+MinifyX.css]]

Вариант 2. Вызываем в собственном сниппете через $modx->runSnippet():
$modx->runSnippet('MinifyX', array('cssSources' => '/css/st.css', 'minifyCss' => 1, 'forceUpdate' => 0,
                                                   'registerCss' => 'placeholder',
                                                   'cacheFolder' => 'css/min/', 'cssFilename' => 'css2'));
return $modx->placeholders['MinifyX.css'];

Так вот. Во втором варианте наблюдаются следующие артефакты (весь кэш в браузере полностью отключил, браузер перезагрузил):

1. Если изменить исходный файл '/css/st.css' и загрузить ту же страницу, то конечный (минимизированный) файл в 'css/min/' не меняется. Т.е. используется старый стиль. До тех пор, пока не очистишь кэш modx. Только после обновления кэша формируется новый минимизированный файл в 'css/min/'. В норме после обновления исходного файла минимизированный файл должен обновляться всегда (т.к. проверяется дата изменения исходного файла).
Данный артефакт наблюдается только во 2-м варианте.

2. Сначала выполняем только 2-й вариант со своим cssFilename ('css2'). Затем выполняем только 1-й вариант с другим cssFilename (css1). В результате в папке 'css/min/' будут лежать 2 файла: css2_хххххххххх.min.css и css1_хххххххххх.min.css. Физически удаляем файл css2_хххххххххх.min.css (созданный 2-м способом — через runSnippet).
После этого наблюдаем такой артефакт: обновляем страницу (с 1-м вариантом) => файл css2_хххххххххх.min.css восстанавливается. Снова удаляем этот файл, обновляем страницу — он снова восстанавливается. Очистка кэша не помогает. При этом сниппет MinifyX, как и положено, работает с файлом css1_хххххххххх.min.css (именно этот файл обновляется при необходимости и именно этот файл указан в теге link страницы). Но в качестве паразитного действия идёт постоянное восстановление файла css2_хххххххххх.min.css (созданного 2-м вариантом через runSnippet), который уже давно никому не нужен.

Такой артефакт наблюдается только после выполнения 2-го варианта (вызываем minifyX через runSnippet) — идёт постоянное восстановление минимизированного файла css2_хххххххххх.min.css, созданного этим вариантом (после его физического удаления).

3. Самый интересный артефакт. Во 2-м варианте ставим 'forceUpdate' = 1:
$modx->runSnippet('MinifyX', array('cssSources' => '/css/st.css', 'minifyCss' => 1, 'forceUpdate' => 1,
                                                   'registerCss' => 'placeholder',
                                                   'cacheFolder' => 'css/min/', 'cssFilename' => 'css2'));
return $modx->placeholders['MinifyX.css'];

(*) Обновляем страницу и получаем: в теге link страницы — один файл (с одним числом), а физически в папке 'css/min/' — другой файл (с другим числом). И при этом страница нормально отображается. Чудо.
При всех последующих обновлениях браузер стили уже не видит, в теге link страницы указывается тот же файл, что был указан после первого обновления страницы, а физически в папке 'css/min/' — файлы постоянно меняются.
Если теперь обновить кэш modx и перезагрузить страницу, то перейдём к (*)

— Все эти 3 артефакта не укладываются в логику кэшированного или некэшированного вызова MinifyX.
Во время тестов кэш браузера полностью отключил, сам браузер перезагрузил. Судя по всему, проблема в «ручном» кэшировании конечных файлов, которое выполняет сниппет MinifyX. Но чем принципиально отличаются эти 2 варианта подключения…
Cyrax_02
12 декабря 2013, 18:44
modx.pro
2 062
0

Комментарии: 20

Aртур Чикин
13 декабря 2013, 07:10
0
MinifyX я думаю нужен в первую очередь для того что бы сжать и кэшировать стили в 1 файл. Если у вас такая жесткая потребность в постоянном обновлении css то вам этот компонент не нужен.
    Cyrax_02
    13 декабря 2013, 08:51
    0
    MinifyX я думаю нужен в первую очередь для того что бы сжать и кэшировать стили в 1 файл.

    Первые 2 артефакта как раз и имеют место при обычном сжатии и кэшировании (при 'forceUpdate' = 0):

    1. Если сниппет вызывать через runSnippet, то изменение исходного файла не приводит к перегенерации выходного (минимизированного) файла до тех пор, пока не будет очищен кэш modx.

    2. Если сниппет вызывать через runSnippet, то сгенерированный в этом случае конечный (минимизированный) файл настолько прочно заседает в кэше modx, что даже при его физическом удалении и очистке кэша modx он всё время пересоздаётся (восстанавливается) заново, даже если мы работает уже с другим минимизированным файлом (имеющим другое базовое имя cssFilename).
    Такой артефакт наблюдается только после выполнения 2-го варианта (runSnippet) при последующих выполнениях 1-го варианта — восстанавливается конечный (минимизированный) файл, созданный 2-м вариантом.

    Если у вас такая жесткая потребность в постоянном обновлении css то вам этот компонент не нужен.
    Речь о 'forceUpdate' = 1?
    Потребности в постоянном обновлении у меня нет. В рабочем состоянии у меня 'forceUpdate' = 0. Но ведь этот параметр реализован не просто так. В случае вызова сниппета через runSnippet и 'forceUpdate' = 1 имеет место 3-й артефакт.
      Aртур Чикин
      13 декабря 2013, 16:21
      0
      Я сказал это к тому что Делаешь верстку. Делаешь сайт. И когда уже все готово потом устанавливаешь MinifyX И забываешь об редактировании верстки. Если сейчас у тебя потребность в постоянном редактировании css и ты не можешь себя удержать в том чтобы не использовать MinifyX. То что тебе мешает пере генерировать стили? используй в формировании ссылки хэш версию что бы браузер перегружал стиль. Динамически меняй переменную &cssFilename = `css1` на новое имя каждый раз как редактируешь стиль.
        Василий Наумкин
        13 декабря 2013, 17:26
        0
        Стоит еще заметить, что больше никто этих «артефактов» не замечал.

        Включая меня.
          Cyrax_02
          13 декабря 2013, 18:02
          0
          Видимо, оттого, что все запускают сниппет так:
          [[!MinifyX? &cssSources=`/css/st.css` &minifyCss = `1` &forceUpdate = `0`
                      ®isterCss = `placeholder`
                      &cacheFolder=`css/min/` &cssFilename = `css1`]]
          [[+MinifyX.css]]

          А артефакты наблюдаются при таком использовании:
          $modx->runSnippet('MinifyX', array('cssSources' => '/css/st.css', 'minifyCss' => 1, 'forceUpdate' => 0,
                                                             'registerCss' => 'placeholder',
                                                             'cacheFolder' => 'css/min/', 'cssFilename' => 'css2'));
          return $modx->placeholders['MinifyX.css'];
            Василий Наумкин
            13 декабря 2013, 18:08
            0
            Тут скорее проблема в плейсхолдере, который вовсе не нужно использовать.

            Смотри параметры registerJS и registerCss — их можно указать = 1, и тогда скрипты и стили будут регистрироваться методами MODX.
              Cyrax_02
              13 декабря 2013, 19:48
              0
              Нет, не в плейсхолдере дело.
              Дело в том, что Minify где-то запомнил (закэшировал) мой вчерашний путь и содержимое вчерашнего минимизированного файла. И при каждом вызове MinifyX этот вчерашний файл по вчерашнему пути постоянно создаётся. При этом в параметрах MinifyX я указываю совсем другие пути и другие имена файлов. Т.е. нормально создаются минимизированные файлы в соответствии с текущими параметрами сниппета, но дополнительно создаётся (обновляется) ещё и вчерашний файл по вчерашнему пути.

              Если указать другую папку или другое имя файла, то ни одного из 3 артефактов не наблюдается (но при этом дополнительно создаётся вчерашний файл по вчерашнему пути).
              Если же указать вчерашнюю папку и вчерашнее имя файла, то начинаются пляски с бубном: MinifyX создаёт минимизированный файл (как положено) и тут же восстанавливает хрен знает откуда вчерашний файл, перезаписывая только что созданный (или меняя его номер).

              Короче, проблема одна — откуда MinifyX берёт содержимое вчерашнего файла и вчерашний путь?
              Кэш modx очищал, кэш браузера полностью очищал, кэширование в браузере полностью отключено.

              ======================
              И ещё одно наблюдение. Если выставить forceUpdate = 0 и изменить что-нибудь в исходном файле, то минимизированный файл пересоздаётся при двух последующих обновлениях страницы, при обновлении в 3-й и последующие разы минимизированный файл остаётся без изменений (как положено).
              Этот артефакт наблюдается при любом способе вызова сниппета MinifyX.

              Может, это из-за отключенного кэширования в браузере?
                Василий Наумкин
                13 декабря 2013, 19:54
                0
                И где же это он может такое запомнить?

                Больше похоже, что у тебя еще где-то есть второй вызов сниппета, со старыми путями. Это объяснило бы многое, в «артефактах».
                  Cyrax_02
                  13 декабря 2013, 22:24
                  0
                  Блин, полтергейст конкретный. Да, все проблемы из-за двойного вызова MinifyX.
                  Только вот второй (проблемный) вызов этого сниппета — это что-то аномальное. С такой флуктуацией я ещё не сталкивался.

                  В общем, вызов сниппета MinifyX выполняется в моём сниппете 'reg_css'. Так вот, в шаблоне страницы сниппет 'reg_css' не вызывается. Сниппет 'reg_css' вызывается вот из-за этой строчки в шаблоне:
                  <img src="images/sun.gif" alt="" class="рcol" />
                  Здесь путь «images/sun.gif» — неправильный (такого файла нет). Если исправить путь либо убрать всю эту строчку, то сниппет 'reg_css' вызываться не будет и паразитный файл хххххххх.min.css создаваться не будет.

                  То, что паразитный вызов MinifyX осуществляется из сниппета 'reg_css' — это точно (проверил). Но с какого перепугу вызывается этот сниппет при указании несуществующей картинки — непонятно.

                  P.S. Всё, завтра с утра к священнику…
                    Василий Наумкин
                    13 декабря 2013, 22:26
                    0
                    На ум приходит только неверная настройка сервера, который при вызове несуществующей картинки запускал дефолтную страницу, а на ней сниппет reg_css.
                      Cyrax_02
                      13 декабря 2013, 22:39
                      0
                      Да, так и есть. При попытке непосредственной загрузки этой картинки загружается главная страница, а там — тот самый вызов reg_css.
                      Обошлось таки без экзорцизма. Завтра займусь сервером…
Cyrax_02
14 декабря 2013, 15:58
0
Двойные вызовы MinifyX исключил. Проверил — никаких артефактов
Тем не менее, одна проблемка осталась:

Вызываю MinifyX некэшированным с &forceUpdate = `0`:
[[!MinifyX? &cssSources=`/css/st.css` &minifyCss = `1` &forceUpdate = `0`
               ®isterCss = `placeholder`
               &cacheFolder=`/css/min/` &cssFilename = `css5`]]
[[+MinifyX.css]]
Далее обновляем страницу: после создания минимизированного файла он не обновляется (как и должно быть).
Изменяем файл "/css/st.css". Снова обновляем страницу: первые 6 обновлений минимизированный файл пересоздаётся, с 7-го обновления пересоздаваться перестаёт. Ситуация стабильная. Проверил 5 раз.

Далее пробую другой вариант — вместо плейсхолдера использую средства modx (registerCss = `default`):
[[!MinifyX? &cssSources=`/css/st.css` &minifyCss = `1` &forceUpdate = `0`
               ®isterCss = `default`
               &cacheFolder=`/css/min/` &cssFilename = `css5`]]
Далее обновляем страницу: после создания минимизированного файла он не обновляется (как и должно быть).
Изменяем файл "/css/st.css". Снова обновляем страницу: первые 7 обновлений минимизированный файл пересоздаётся, с 8-го обновления пересоздаваться перестаёт (может, ошибся на 1).

Таким образом, получается, что после изменения исходного файла минимизированный файл при последующих обновлениях страницы пересоздаётся несколько раз, после чего не меняется. Почему он пересоздаётся несколько раз вместо одного?
    Василий Наумкин
    14 декабря 2013, 17:19
    0
    Потому что у тебя очень странный сервер.
      Cyrax_02
      14 декабря 2013, 19:15
      0
      У тебя там время изменения минимизированного файла неправильно выставляется. После первого обновления страницы (после изменения исходного файла) оно примерно на минуту меньше, чем время изменения исходного файла. И при каждом обновлении страницы создаётся новый минимизированный файл (по понятным причинам), при этом время его изменения понемногу увеличивается. И когда время его изменения перевалит за время изменения исходного файла, обновляться он перестаёт.
        Cyrax_02
        14 декабря 2013, 19:22
        0
        Похоже, дело в WinSCP. Он у меня локальное (виндовое) время выставляет, а MinifyX — серверное.
          Cyrax_02
          14 декабря 2013, 19:37
          0
          Да, так и есть. Если менять исходный файл средствами modx, то время его изменения выставляется серверное и минимизированный файл обновляется только 1 раз.
      Cyrax_02
      15 декабря 2013, 12:44
      0
      Проблема №3. При одинаковых cssFileName MinifyX почему-то работает с одним и тем же файлом для разных наборов исходных файлов.
      Например, для одной страницы (шаблона) указываем один набор параметров. Загружаем страницу => MinifyX создаёт минимизированный файл.
      Далее на другой странице вызываем MinifyX с другим набором исходных файлов, но с тем же cssFileName. Загружаем эту страницу. В итоге MinifyX ничего не создаёт и подключает уже существующий минимизированный файл (содержащий стили для предыдущей страницы). Со всеми вытекающими.

      Для обхода проблемы приходится для каждого набора подключаемых файлов указывать разные cssFileName.
        Cyrax_02
        16 декабря 2013, 18:49
        0
        Василий, это штатное (задуманное) поведение MinifyX или нет?
          Василий Наумкин
          16 декабря 2013, 19:25
          0
          Тебя самого не удивляет, сколько у тебя проблем с одним сниппетом? Особенно при том, что у других людей таких вопросов вообще не возникает?

          Вот тебе исходный код, ищи ошибку — там всего 266 строк. Если найдешь — исправлю.

          Самому мне что-то надоело уже разбираться.
            Cyrax_02
            19 декабря 2013, 17:40
            0
            Вот тебе исходный код, ищи ошибку — там всего 266 строк. Если найдешь — исправлю.

            Ну… ошибки обычно ищут в имеющемся функционале. А если у тебя нет проверки набора исходных файлов? Где ошибку-то искать? Здесь уже корректнее говорить не о поиске ошибок, а о доработке функционала.

            Вот как у тебя формируется имя готового файла:
            $file = $this->config['jsFilename'] . '_' . $time . $this->config['jsExt'];
            Здесь присутствует только время создания. А информации о наборе исходных файлов, которым соответствует этот минимизированный файл, нет. Напрашивается добавить ещё и хэш от набора полных имён исходных файлов.

            Вот здесь выполняется поиск минимизированных файлов, имеющих в имени baseFilename, '_' и 10 цифр, тогда как такие минимизированные файлы могут соответствовать совсем другим наборам исходных файлов:
            <pre class="prettyprint">// Get the latest cache files
                            $this->config['cacheFolder'] = $cacheFolder = MODX_BASE_PATH . $full_path;
                            $regexp = '('.$this->config['jsFilename'].'|'.$this->config['cssFilename'].')';
                            $regexp .= '_(\d{10})';
                            $regexp .= '('.$this->config['jsExt'].'|'.$this->config['cssExt'].')';
            
                            $files = scandir($cacheFolder);
                            foreach ($files as $file) {
                                    if ($file == '.' || $file == '..') {continue;}
            
                                    if (preg_match("/^$regexp$/iu", $file, $matches)) {
                                            if ($matches[3] == $this->config['jsExt']) {
                                                    $this->current['js'][] = array(
                                                            'file' => $matches[0],
                                                            'time' => filemtime($cacheFolder . $file),
                                                    );
                                            }
                                            else {
                                                    $this->current['css'][] = array(
                                                            'file' => $matches[0],
                                                            'time' => filemtime($cacheFolder . $file),
                                                    );
                                            }
                                    }
                            }


            Особенно при том, что у других людей таких вопросов вообще не возникает?

            Причин много:
            1. На разных страницах сайта подключают одинаковые наборы файлов. В этом случае озвученная проблема себя никак не проявит.
            2. Указывают разные базовые имена на каждой странице портала. В этом случае озвученная проблема себя никак не проявит.
            3. Те, кто сталкивается с проблемами в работе MinifyX, отказываются от этого сниппета, не разобравшись в причинах проблем. Например, Муравьев Артём. Не все же могут себе позволить «торчать» с каждым сниппетом по 3 недели.
            4. Ещё не обратили внимания на проблему.
            5. Скромничают.
            6. Перешли на другую CMS.
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        20