Почему после деплоя пользователи видят старые стили и скрипты
После деплоя бывает странная ситуация: разработчик видит новые стили, а пользователь продолжает видеть старую верстку. Или часть страниц выглядит нормально, а часть сломана. Часто причина не в самом CSS или JS, а в кэше браузера, CDN, nginx или механизме assets в Yii2.
Такие проблемы особенно неприятны после изменения структуры HTML: старый JavaScript работает с новой разметкой или новый CSS не применяется к старому файлу из кэша.
Сначала понять, какой файл загружается
В браузере нужно открыть DevTools, вкладку Network, отключить кэш и посмотреть URL CSS и JS. Важно увидеть не только имя файла, но и код ответа, размер, дату и заголовки cache-control.
curl -I https://example.ru/css/site.css
curl -I https://example.ru/assets/app.js
Если сервер отдаёт старый файл, проблема на стороне деплоя или серверного кэша. Если сервер отдаёт новый, а пользователь видит старый, вероятнее браузерный кэш или CDN.
Версионирование файлов
Самый надёжный способ не спорить с браузером — менять URL ресурса при изменении содержимого. Например, добавлять версию:
<link rel="stylesheet" href="/css/site.css?v=20260630">
В Yii2 можно настроить assetManager, чтобы версии добавлялись автоматически по времени изменения файла.
'assetManager' => [
'appendTimestamp' => true,
],
Это удобно для небольших проектов. Для крупных сборок обычно используют имена файлов с hash, которые формируются сборщиком.
Yii2 web/assets
Yii2 публикует ресурсы расширений и asset bundles в web/assets. После обновления пакетов или bundle-файлов иногда нужно очистить опубликованные assets.
rm -rf web/assets/*
Удалять нужно содержимое web/assets, а не саму директорию. После удаления Yii2 опубликует ресурсы заново. Важно, чтобы у веб-сервера были права на запись.
ls -la web/assets
chown -R www-data:www-data web/assets
AssetBundle и depends
Если JavaScript подключается не в том порядке, проблема может выглядеть как кэш. Например, скрипт зависит от jQuery, но подключился раньше.
class AppAsset extends AssetBundle
{
public $basePath = '@webroot';
public $baseUrl = '@web';
public $css = [
'css/site.css',
];
public $js = [
'js/app.js',
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
];
}
После изменений в AssetBundle стоит проверить исходный HTML страницы и порядок подключений.
Кэш nginx
Если nginx отдаёт статику с долгим expires, браузер может долго не запрашивать новый файл. Это нормально для файлов с версией в URL, но плохо для файлов без версии.
location ~* \.(css|js|png|jpg|jpeg|gif|webp|svg|ico)$ {
expires 30d;
add_header Cache-Control "public";
}
При такой настройке файл site.css без версии может застрять у пользователя надолго. Поэтому долгий кэш лучше сочетать с версионированием.
CDN и прокси
Если перед сайтом стоит CDN или прокси-кэш, очистка web/assets на сервере не гарантирует, что пользователь увидит новый файл. Нужно отдельно сбросить кэш CDN или поменять URL ресурса.
Признак CDN-кэша — разные ответы при запросе напрямую к серверу и через домен. На практике это проверяют заголовками и временным обходом CDN, если есть доступ.
Старый HTML и новый JS
Иногда проблема не в файлах, а в несовместимости. Например, HTML обновился, классы кнопок изменились, а старый JS из кэша ищет прежние селекторы.
$(document).on('click', '.js-submit-order', function () {
// обработчик
});
Если класс переименовали в js-order-submit, старый скрипт уже не найдёт кнопку. Поэтому при изменении HTML и JS лучше обновлять версию обоих ресурсов.
Проверка после деплоя
- Открыть страницу с отключенным кэшем в DevTools.
- Проверить URL CSS и JS.
- Проверить заголовки cache-control.
- Очистить web/assets при необходимости.
- Проверить права на web/assets.
- Убедиться, что у файлов есть версия или hash.
- Проверить CDN или прокси-кэш.
- Проверить консоль браузера на ошибки JS.
Кэш статики нужен для скорости, но после деплоя он должен быть управляемым. Если файл может измениться, его URL тоже должен меняться. Тогда пользователю не придётся чистить кэш вручную, а разработчику — объяснять, почему “у меня всё работает”.
Комментарии (0)
Пока нет комментариев. Будьте первым!