Почему битый CSS и JS ломают SEO и как это починить

Битый CSS или JavaScript — это когда страница просит файл стилей или скрипта, которого на сервере уже нет, и браузер получает ошибку 404. На первый взгляд мелочь в консоли, но без стилей текст теряет читаемость, а без скрипта не работают меню, формы и аналитика. Разбираем, почему такая ошибка бьёт по SEO и UX, как найти несуществующие ассеты и что с этим делать на практике.

Почему битый CSS и JS портят SEO и UX

Поисковики больше не видят сайт как набор статичных страниц: они прогружают его, как обычный пользователь. Если после загрузки страницы нет стилей или ключевой скрипт падает с 404, робот видит «пустой» интерфейс и может оценить контент ниже. На практике это проявляется так:

  • Потеря читаемости. Без CSS текст съезжает, наезжает друг на друга, кнопки сливаются. Пользователь не может понять, что делать дальше, и уходит.
  • Сломанный функционал. Меню-бургер, форма заявки, калькулятор, модальные окна — всё это на JS. Если скрипт сломан, пользователь не оставляет заявку, а вы теряете лид.
  • Упавшая аналитика. Без рабочего скрипта счётчика вы не видите трафик и не настраиваете воронки. Отсюда неверные решения по сайту.
  • Плохие поведенческие сигналы. Медленная или сломанная страница увеличивает отказов и снижает время на сайте — косвенный сигнал для поисковика.

Частая причина — рассинхронизация версий: новый файл с хешем уже опубликован, а HTML, кэш CDN или service worker всё ещё ссылаются на удалённый предыдущий chunk. То есть сам файл на месте, но ссылка на него устарела.

Причина Признак Исправление
Старый HTML в кэше Запрашивает прошлый hash Инвалидировать HTML вместе с релизом
Неверный public path 404 на вложенном URL Исправить путь в конфигурации сборки
Рано удалённый chunk Ошибка после обновления вкладки Хранить несколько версий ассетов
Виджет недоступен 403/5xx чужого домена Проверить необходимость и fallback

Отдельно стоит помнить: ошибка не всегда равна 404. Код 304 означает, что браузер использует валидную кэшированную копию после проверки свежести — это норма. Проблема начинается, когда HTML просит файл, которого сервер или CDN уже не знает. Поэтому смотреть нужно на связку URL, статуса и версии релиза, а не на один код ответа. Подробнее о том, как сайт видит робот и почему 304/404 путают индексацию, читайте в статье Как проверить сайт глазами робота.

Как найти несуществующие файлы стилей и скриптов (инструменты, DevTools)

Главный инструмент — это Network в DevTools. Действуем по шагам:

  1. Откройте страницу в новом профиле браузера. Чистый профиль без расширений и старого кэша показывает реальную картину релиза, а не то, что «у меня локально работает».
  2. Переключитесь на вкладку Network и отфильтруйте по JS/CSS. Загрузите страницу заново (Ctrl+Shift+R для жёсткого рефреша).
  3. Посмотрите статусы ответов. Всё, что не 200 — 404, 403, 5xx или загрузка с редиректом, сразу бросается в глаза красным.
  4. Сравните URL в HTML с manifest текущей сборки. Так видно, какой именно компонент устарел: HTML ссылается на старый hash, а на сервере лежит новый файл.
  5. Проверьте несколько страниц. Не только главную, но и форму, каталог, вложенный маршрут — ошибки publicPath часто проявляются именно там, где меньше статичного кода.

Полезно прогонять проверку не вручную, а через автоматизированные инструменты. Например, бесплатная проверка сайта покажет доступность страницы и типичные технические проблемы одним кликом, а инструмент Page size оценит вес ресурсов, которые браузер пытается загрузить.

Для точной диагностики пригодится и простой curl:

# Нормальный ответ для ассета
curl -I https://example.ru/_nuxt/app.abc123.js
# HTTP/2 200
# content-type: application/javascript

Если в ответе вместо 200 — 404 или неверный content-type, значит ассет недоступен по этому пути и нужно править сборку или кэш.

Отдельного внимания заслуживают коды 403 и 5xx: они редко означают битый файл, но ломают страницу так же, как 404. Код 403 обычно говорит о том, что у ассета неправильные права доступа на сервере или CDN закрыл доступ по правилу, а 5xx — это ошибка самого сервера или провайдера. В обоих случаях страница теряет ресурс, поэтому в списке проблем они стоят рядом с классическим 404.

Влияние на скорость загрузки и индексацию

Битые ассеты бьют сразу по двум направлениям: по скорости и по индексации.

Скорость. Когда браузер ждёт ответ от несуществующего файла, он тратит время на таймауты и повторные попытки. Пустые места вместо стилей и скриптов создают эффект «прыжка макета» (CLS), а критический CSS может не загрузиться вовсе. В связке с render-blocking ресурсами это сильно растягивает время до интерактивности, особенно на мобильных.

Индексация. Поисковый робот ожидает, что страница отдала полный набор ресурсов. Если CSS/JS падают с ошибкой, скрейпинг видит упрощённый или сломанный DOM: часть контента может не попасть в индекс, а структура страницы будет оценена неверно. Плюс старый service worker способен отдавать уже несуществующий shell приложения — робот получает ещё один слой рассинхрона.

На практике это бьёт по Core Web Vitals: критический CSS не загрузился — страдает LCP, пустые места вместо элементов — CLS, а ожидание таймаута по битым файлам растягивает TTI. Все эти метрики участвуют в ранжировании, поэтому чистый набор ассетов — это прямо техническая SEO-составляющая, а не только «чтобы было красиво».

Отсюда вывод: чистый Network без 404-ных ассетов — это и про скорость, и про то, насколько качественно поисковик поймёт ваш контент.

Как исправить — проверить пути, редиректы, 404 для статики

Конкретные действия, которые устраняют проблему у себя:

  1. Проверьте путь к ассетам (publicPath). Если 404 выпадает на вложенном URL, скорее всего, в конфигурации сборки неверно задан базовый путь. Исправьте его и пересоберите проект.
  2. Инвалидируйте HTML вместе с релизом. Раз файлы с хешем меняются от релиза к релизу, старый закэшированный HTML должен быстро получить новую ссылку. Иначе браузер долго ходит по старому chunk.
  3. Настройте раздельный кэш. Для файлов с хешем допустим долгий cache-control — они не меняются. А вот HTML должен обновляться быстро. Не отключайте кэш для всех ассетов навсегда: это сделает повторные посещения медленнее и не уберёт рассинхронизацию версий.
  4. Храните несколько версий ассетов. Рано удалённый chunk вызывает ошибки после обновления вкладки. Оставьте старые файлы на пару дней-неделю, пока они ещё могут запрашиваться открытыми вкладками.
  5. Обновляйте service worker отдельно. Старый worker отдаёт устаревший shell — выкатывайте новую версию и обрабатывайте ошибку загрузки чанка, чтобы пользователь не видел пустой экран.
  6. Проверьте сторонние виджеты. Если 403/5xx приходит с чужого домена, оцените, нужен ли виджет вообще, и предусмотрите fallback — иначе одна внешняя зависимость ломает страницу.

Важно: не «лечите» проблему отключением кэша или минификацией как способом закрыть симптом. Эти приёмы маскируют рассинхронизацию, но не убирают её причину. Для файлов с хешем долгий кэш — это норма и даже преимущество, если правильно обновляется HTML. О тонкостях кэширования и сжатия читайте в статье Gzip и кеширование.

Как проверить в seoquest.ru (/check/free)

Если не хочется вручную бить по всем страницам, прогоните сайт через бесплатную проверку на [/check/free]. Инструмент покажет доступность страницы и типичные технические проблемы одним кликом — в том числе те самые 404 и нерабочие ресурсы, которые портят и SEO, и пользовательский опыт.

Чтобы проверка была максимально полезной:

  • Выберите несколько критичных сценариев. Не только главную, но и форму, каталог, кабинет — там чаще всего прячется неверный путь или отсутствующий chunk.
  • Сравните результат с Network в DevTools. Автоматическая проверка даёт общую картину, а DevTools показывает точные URL и статусы — вместе это быстрее выявляет корень проблемы.
  • Запустите проверку после каждого релиза. Такой smoke тест быстро ловит рассинхронизацию версий ещё до того, как она скажется на трафике.

Похожий по духу подход — к приоритизации и автоматизации технических правок. О том, как системно найти и исправить битые ссылки, чтобы не терять вес страниц и не ломать навигацию, читайте в отдельной статье.

Часто задаваемые вопросы

Означает ли 404 на CSS или JS, что всё сломано?

Не всегда. Сначала смотрите на связку URL, статуса и версии релиза. Если это 304 — браузер использует валидную кэшированную копию, и проблема не здесь. Настоящая ошибка, когда HTML просит файл, которого сервер или CDN уже не знает.

Нужно ли отключить кэш для всех ассетов?

Нет. Это сделает повторные посещения медленнее и не устранит рассинхронизацию версий. Для хешированных файлов полезен долгий кэш, а HTML должен быстро обновляться. Продуманное правило кэша надёжнее, чем постоянная инвалидация всего сайта.

Почему ошибка видна только после обновления страницы?

Открытая вкладка могла сохранить старый runtime, который пытается догрузить прежний chunk после нового релиза. Храните старые ассеты некоторое время и обрабатывайте ошибку загрузки чанка — это мягче, чем заставлять пользователя увидеть пустой экран.

Достаточно ли проверить главную после деплоя?

Нет. Главная часто использует меньше кода, чем каталог, форма или кабинет. Выберите несколько критичных пользовательских сценариев и вложенный маршрут — такой smoke тест быстрее выяляет неверный путь, отсутствующий chunk и ошибку сторонного виджета.

Читайте также