Как заставить CSS и JS обновляться автоматически при обновлении файлов
У нас на сервере включена полезная опция объединения всех JS и CSS файлов. Задается она в конфиге
Однако при обновлении исходников JS и CSS файлов пользователи не получают обновления. Я видел есть плагин ReloadCSS однако он не занимается JS файлами, плюс тыкать кнопку мне тоже не охота совсем. В итоге я полез в код движка и нашел место, где формируется название скомпрессированных файлов
engine/modules/viewer/Viewer.class.php функция Compress
Видно, что в формировании ключа участвуют только имена файлов. Я добавил туда еще и размеры, заодно проверил скорость формирования ключа. Вот такой код у меня получился:
Проверка показала, что время пренебрежимо мало:
Убираем отладочный вывод и радумеся обновлениям JS и CSS.
Можно было бы это сделать плагином, но в плагине пришлось бы переопределить функцию Compress. Может, лучше это изменение просто включить в следующую версию LS.
/** * Параметры компрессии css-файлов */ $config['compress']['css']['merge'] = true; // указывает на необходимость слияния файлов по указанным блокам. $config['compress']['js']['merge'] = true;
Однако при обновлении исходников JS и CSS файлов пользователи не получают обновления. Я видел есть плагин ReloadCSS однако он не занимается JS файлами, плюс тыкать кнопку мне тоже не охота совсем. В итоге я полез в код движка и нашел место, где формируется название скомпрессированных файлов
engine/modules/viewer/Viewer.class.php функция Compress
/** * Сжимает все переданные файлы в один, * использует файловое кеширование * * @param array $aFiles Список файлов * @param string $sType Тип файла - js, css * @return array */ protected function Compress($aFiles,$sType) { $sCacheDir = $this->sCacheDir."/".Config::Get('view.skin'); $sCacheName = $sCacheDir."/".md5(serialize($aFiles).'_head').".{$sType}"; $sPathWeb = Config::Get('path.root.web'); /** * Если кеш существует, то берем из кеша */ if(!file_exists($sCacheName)) {
Видно, что в формировании ключа участвуют только имена файлов. Я добавил туда еще и размеры, заодно проверил скорость формирования ключа. Вот такой код у меня получился:
/** * Сжимает все переданные файлы в один, * использует файловое кеширование * * @param array $aFiles Список файлов * @param string $sType Тип файла - js, css * @return array */ protected function Compress($aFiles,$sType) { $sPathWeb = Config::Get('path.root.web'); $aFileDates = array(); $iStart = microtime(true); foreach ($aFiles as $sFile) { // если файл локальный if (strpos($sFile, $sPathWeb)!==false) { $sFile=$this->GetServerPath($sFile); list($sFile,)=explode('?',$sFile,2); $aFileDates[] = filectime($sFile); } } $sCacheDir = $this->sCacheDir."/".Config::Get('view.skin'); $sCacheName = $sCacheDir."/".md5(implode($aFiles).implode($aFileDates).'_head').".{$sType}"; echo "Key calculation took ".(microtime(true) - $iStart)." secs\n"; /** * Если кеш существует, то берем из кеша */ if(!file_exists($sCacheName)) {
Проверка показала, что время пренебрежимо мало:
Key calculation took 0,0016648769378662 secs Key calculation took 0,0010089874267578 secs
Убираем отладочный вывод и радумеся обновлениям JS и CSS.
Можно было бы это сделать плагином, но в плагине пришлось бы переопределить функцию Compress. Может, лучше это изменение просто включить в следующую версию LS.
16 комментариев
Для CSS/JS я бы не ставил — много ничего не выиграете, это все равно ничтожные копейки учитывая сжатие респонса.
У меня JS и CSS выдает nginx без каких-либо заголовков типа expires или no-cache. В итоге, браузер сам решает на сколько кэшировать. Вот что-то невнятное пишут в интернетах на этот счет http://stackoverflow.com/questions/9740822/how-long-does-google-chrome-cache-a-resource-if-expires-and-or-no-cache-headers
Можете зайти своим любимым браузером на http://www.7dach.ru и проверить, как часто браузер проверяет не обновились ли подключенные css/js.
Сохраняю измененый css-файл в Coda переключаю активное окно и сразу вижу изменения! Восхитительно!