Миграция на SPA стоила –25% органики. Как мы вернули рост – и зачем сайту «релиз-гейт»
Миграция сайта на SPA – это тот случай, когда решение принимают разработчики, а последствия первым видит маркетолог: в отчете по органическому трафику. Рассказываем кейс нашего клиента – национальной сети ремонта турбокомпрессоров с интернет-магазином на ~3000 товаров. В кейсе две итерации фронтенда: первая – SPA на JavaScript с самописным фреймворком, после которой органика упала; вторая — переписка на React с SSR, которая прошла через релиз-гейт. Сюжет честный, без «переехавших идеально» и без «все пропало»: просадка и остановка роста при удержанных топах, диагностика, программа исправлений, релиз через формальные критерии приемки – и возврат к росту.
Сразу терминология, чтобы дальше говорить на одном языке. SPA (одностраничное приложение) — приложение, где браузер получает почти пустой HTML, а все содержимое дорисовывает JavaScript. SSR (рендеринг на стороне сервера) — подход, при котором сервер отдает уже готовый HTML с текстом, заголовками и ссылками, а JavaScript только «оживляет» страницу. Для пользователя разница незаметна. Для поискового бота – критическая.
Акт 1. Контекст: стабильная органика и бизнес-решения о переезде
Клиент – сеть с филиалами по Украине: ремонт турбокомпрессоров плюс каталог запчастей на ~3000 SKU, двуязычный сайт. Органика стабильна: за SimilarWeb – около 6 941 десктоп-визитов в месяц. Двигатель канала – категории и карточки товаров: для e-commerce именно они собирают коммерческий спрос (как это работает системно – разбирали в гайде о [SEO для интернет-магазинов → pillar-3]).
Решения о переезде со старого PHP-сайта на современный JavaScript-стек приняли из соображений продукта: более быстрый интерфейс, удобство разработки, редизайн. Первая итерация выглядела так: бэкенд – Node.js, фронтенд – SPA на JavaScript с собственным, самописным фреймворком. Классическая ситуация, которую мы видим регулярно: стек выбрали с точки зрения разработки – а SEO-последствия не просчитывал никто.
Акт 2. Просадка: −25% трафика и остановка роста
Новую SPA-версию задеплоили [дата деплоя, 01-02.2026]. Сразу после переезда органический десктоп-трафик просел на 25%: с ~6 941 до 5 197 визитов в месяц.
Первое, что хочется сказать в такой ситуации, – «рынок просел». Мы проверили. Рынок действительно был беспокоен, но неоднороден:
Сайт | Динамика 02.2026 |
|---|---|
Клиент | −25% |
Конкурент №1 | −52% |
Конкурент №2 | +26% |
Один игрок потерял половину, другой – вырос на четверть. Списать все на сезон или рынок не получилось. Причину нужно было искать в самом сайте.
И здесь важна честная деталь, отличающая этот кейс от историй о катастрофе. Сайт не обрушился: по ключевым запросам он в целом удержался в топах. Но он перестал расти – при живом спросе и активном рынке. Для владельца такая картина часто выглядит как «все хорошо, просто период такой». Для нас стагнация на фоне сохраненного спроса – симптом нездоровья. Именно она, а не только -25%, стала сигналом идти в глубокий аудит.
Акт 3. Диагностика: что на самом деле увидел Googlebot
Здесь началась самая важная часть кейса. Мы сняли страницы по протоколу «сырой HTML без выполнения JavaScript» – то есть посмотрели на сайт глазами бота в момент первого запроса (отдельная причина делать это собственным протоколом: датацентровые запросы сайт отсекал на уровне Cloudflare, поэтому вопрос «откуда видит бот» требовал отдельной проверки).
Сразу расставим акценты, потому что здесь легко перекрутить. Googlebot не был слепым: контент на сайте существовал, и после рендеринга JavaScript бот его получал. Проблема в другом – контента не было в HTML. Он жил в JavaScript-контейнере и этот контейнер тянул на каждую страницу почти всю структуру сайта. Первичный аудит свелся к четырем находкам:
- Нет HTML. В сыром HTML – ноль контента: весь текст, ссылки и заголовки сидели внутри JS-контейнера.
- Бот получал данные не с первого мероприятия. Первый запрос отдавал пустой каркас; настоящее содержимое Google видел только после рендеринга JavaScript – из очереди, живущей своим расписанием.
- Большой размер страниц. До 1 МБ HTML на страницу при норме <150 КБ.
- Открытые данные для парсинга. JSON-контейнер с контентом и почти полной структурой сайта лежал открытым на каждой странице – любой парсер мог снять каталог и все SEO-тексты одним запросом.
В цифрах первый запрос бота выглядел так:
Что проверяли (сырой HTML) | Факт после переезда (аудит 03.2026) |
|---|---|
Ссылки <a href>в<тело> поза <script> | 0 (из 346 на главной для пользователя) |
Метка H1 | 0 |
Текст поза скриптами | 0 символов |
Изображение | 0 |
Вес HTML страницы | к 1 МБ при норме <150 КБ; /site-map — 5,5 МБ |
Встроенная полезная нагрузка | 727 КБ в одном скрипте |
Отдельная деталь, которую любят разработчики: переменная со всем этим состоянием называлась ssrdata – но ни одного Server-Side Rendering она не делала.
Масштаб контейнера лучше всего показывает страница услуг: 303 tag H2, из которых по теме – всего 6. Остальные – SEO-тексты других страниц, «ехавших» в payload меню на каждую страницу на двух языках (~90 КБ чужого контента, на странице контактов – 26 полных текстов других разделов). 43% JSON-payload – внутренние дубли; собственный контент страницы – 2,9%.
Почему это тормозит рост – механика простыми словами. Google обрабатывает JavaScript-сайты в фазы: сканирование сырого HTML происходит сразу, а рендеринг JavaScript стоит в отдельной очереди, которая может растягиваться.Google Search Central: Понимание основ SEO на JavaScript).
Ключевая инженерная деталь: новые URL Google открывает через ссылку, а ссылку бот находит только в элементах <a> с атрибутом href. Нет их в сыром HTML – краулер не может вовремя строить граф связей для новых и обновленных страниц: это удар сразу по discovery и краулинговому бюджету. Старые страницы ранжируются по сохранившемуся историческому индексу — поэтому топы держались. А новые посадочные, обновленные карточки и свежие тексты вскакивают «вторым темпом» и зависают «сиротами» – поэтому роста не было: все новое бот видел поздно и дорого.
Для специалистов — врезка: в типичных провальных миграциях на SPA потери составляют −60…80% органики. Здесь просадка остановилась на −25%, и это не везение. При переезде команда сохранила 100% URL-структуры (ноль 404), корректные hreflang, canonical и schema.org. Это «миграционная гигиена» – именно она удержала позиции в топах, пока рендеринг-долг съедал потенциал роста. Как мы находим такие вещи системно – отдельный материал: [кейс технического SEO-аудита → article-6].
Акт 4. Программа действий: два параллельных трека
Исправление разложили на два трека, которые шли одновременно.
Трек А – технический. Требования к разработчикам: внедрить SSR (H1, текст, меню, ссылки на товары и изображения – в сыром HTML для выполнения JS); «payload-диета» – вычистить из пейлоада чужие SEO-тексты, дубликаты и неиспользуемую языковую версию с планом 727 КБ → 60–90 КБ; исправить soft-404, раздутые title, пагинацию; добавить lazy loading и коммерческую Schema.org (ItemList/Product/AggregateRating). Команда разработки решила закрывать эти требования второй итерацией – переписыванием фронтенда с самописного фреймворка на React с SSR.
Трек Б – контентно-структурный. Пока разработчики строили SSR, работали с тем, что не зависит от релиза: новые посадочные под узкие услуги (актуатор, диагностика) и региональные страницы; переоптимизация страниц под реальный интент – показательный случай: страница была заточена под «очистку» DPF, а частотный запрос рынка – «промывка»; системная работа с отзывами в Google Business Profile.
Local SEO дало самый наглядный урок кейсу. Филиал в одном из областных центров держит Local Pack #1 с рейтингом 4.9 и 143 отзывами – против конкурента с 839 отзывами, но рейтингом 4.3. Качество отзывов весит больше количества.
Акт 5. Релиз-гейт: почему мы не пропустили релиз разработчиков
Когда разработчики представили вторую итерацию – фронтенд, переписанный на React с SSR, – ее можно было просто выпустить. Мы не упустили.
Аудит прототипа по тому же протоколу сырого HTML показал 9 регрессов против 5 улучшений: 50 битых изображений, H1 главной «прибит» к первому слайду рекламного баннера, canonical на чужой хост, отсутствует sitemap, конфликтный robots.txt. Второе падение трафика бизнес мог и не пережить.
Разработчики спешили. Мы – нет.
Прототип вернули на доработку – не с комментарием «что-то не так», а с формальными критериям приемки, которые проверяются на сыром HTML без выполнения JS:
Критерий приемки релиза | Порог |
|---|---|
Ссылки меню и товаров как <a href> | ≥30 в сыром HTML |
H1 | 1, релевантный странице |
Текст поза скриптами | ≥1500 символов |
Вес страницы | <150 КБ |
Битые изображения | 0 |
Карта сайта | валидный |
Канонический | самореферентность |
Это и есть «релиз-гейт»: страховка, которая стоит один аудит – и всегда дешевле второго падения трафика. Именно поэтому мы считаем, что SEO-требования должны сидеть в ТС на разработку сайта с первого дня, а не появляться после релиза.
Акт 6. Релиз и цифры «до → после»
React-версию из SSR выкатили на прод [точная дата SSR-релиза, 08.2026]. Контрольный аудит по критериям приемки: 7 из 9 выполнены полностью. Ключевые измерения:
Метрика | После переезда (03.2026) | После SSR-релиза (22.08.2026) |
|---|---|---|
Вес HTML главной | 978–1210 КБ | 108 КБ (−91%) |
<a href> в сыром HTML главном | 0 | 179 |
H1 в сыром HTML | 0 | 1 на каждой странице |
Текст вне скриптов (главный) | 0 символов | 11 093 |
Встроенная полезная нагрузка | 727 КБ | 32 КБ (−96%) |
H2 на странице «Ремонт турбин» | 303 | 10 |
Чужие SEO-тексты на страницах | ~90 КБ | 0 |
Страница /site-map | 5 505–5 687 КБ | 136 КБ (−98%) |
Несуществующий URL | 200 (soft-404) | 404 |
Title пагинации | дубли на 148 страницах | уникальные («Страница №2»…) |
Schema категорий | Статья (не относящаяся к делу) | ItemList + Product + Offer + BreadcrumbList + FAQPage |
Schema товара | базовая | Продукт + Бренд + Предложение + Сводный рейтинг + Страница часто задаваемых вопросов |
Битые изображения (главная/категория) | 18 / 32 (прототип) | 0 / 0 |
loading=»lazy» | 0 из 63 изображений | 91 із 94 (герой — нетерпеливый + приоритет получения = высокий) |
TTFB / полная загрузка главной | FCP 1,7 с «на пределе» | 206 мс / 2,0 с |
Sitemap-инфраструктура | частично | 2 индекса × 15 карт + карта изображений (10,5 тыс. URL) |
А теперь – самое важное о честности цифр. Рост начался еще до SSR-релиза: по GA4 клиента, organic + direct добавили +20% за 05–08.2026 [скриншот GA4]; независимый срез SimilarWeb от 12.08.2026 – 37,3 тыс. визитов за 3 месяца, +16,8% за последний месяц, органика – топ-источник с долей 36%. Это результат контентно-структурного трека Б – не SSR. Эффект самого SSR-релиза на индексацию и позиции фиксируется в Search Console отдельно через 4–6 недель после релиза [график GSC — вставить]. Мы сознательно не смешиваем эти два эффекта: методология дала результат еще до главного технического фикса – и это более сильный аргумент, чем SSR все спас.
Что еще не закрыто – говорим прямо
Кейс не закончен, и мы не будем делать вид, что все идеально. В беклозе после релиза: H1 главной до сих пор привязан к первому слайду баннера (хотфикс №1); отдельные тяжелые каталожные шаблоны до сих пор весят 210–278 КБ при цели <150 КБ – главная уже 108 КБ, но не все типы страниц дотянулись до нее (и это уж точно не 1 МБ); длинные title карточек товаров (140–156 символов – было 447); alt-атрибуты отсутствуют в ~65% изображений; параллельные namespace /каталог/*и/категория/*; одна внутренняя ссылка на 404 со страницы услуг. Это нормальное состояние живого проекта: релиз закрыл критическое, далее – плановая работа.
Как мы ведем миграции в ADS group
Миграция – это всегда две команды в одной связке. У нас это устроено так: Dev-Unit строит приложение, SEO-Unit формулирует требования к сырому HTML еще на этапе ТС, ведет диагностику по собственному аудит-протоколом – и имеет право не пропустить релиз, пока критерии приемки не выполнены. Именно эта конструкция в кейсе сработала дважды: сначала обнаружила истинную причину падения, затем остановила релиз с 9 регрессами. Если вам предстоит переезд на новый фронтенд – правильный момент прийти на технический SEO-аудит – до релиза, а не после падения.
Чек-лист: миграция на SPA без SEO-катастрофы
До миграции: зафиксировать базлайн (трафик, позиции, полный список URL); внести SSR или пре-рендеринг в ТС подрядчику – «потом докрутим» не работает; сохранить 100% URL или подготовить карту 301.
Критерии приемки релиза — проверяются на сыром HTML, без выполнения JS: ссылки меню и товаров как <a href>; один релевантный H1; основной текст присутствует; вес страницы <150 КБ. Canonical – только self-referencing. Sitemap – валидный, без мусорных URL. 404 отдает 404, а не soft-200. Ноль битых изображений, lazy loading на всем, кроме hero.
После релиза: снять стейджинг-noindex по регламенту; прогнать ключевые шаблоны через GSC Live Test; поставить annotation дать релизу в аналитике; мониторить статистику сканирования (размер ответа должен упасть, количество сканирований – возрасти); контрольный срез позиций через 4-6 недель.
Отдельно: WAF/Cloudflare может резать краулеров независимо от robots.txt – исключение для Verified Bots обязательно.
Это критерии для SPA-переезда. Полная процедура любой миграции – домен, CMS, структура URL, карта редиректов, staging – в нашем отдельном материале: [чек-лист миграции сайта → article-5].
Миграция на SPA не приговор для органики – приговор, когда сырой HTML пуст, а релизы получаются без критериев приемки. Фреймворк здесь ни при чем: в этом кейсе падение дал самопишущийся JavaScript-фронтенд без SSR, а восстановление закрепила React-версия, которую пропустили на прод только через релиз-гейт. Бизнес потерял 25% органики из-за того, что SEO позвали после деплоя — и рост стартовал еще до главного технического фикса, когда появились диагностика и два трека работ.
Если вы планируете редизайн или смену фронтенда – сосчитайте стоимость аудита до миграции и сравните с ценой нескольких месяцев проселенной органики. Закажите аудит перед миграцией или разработку, где SEO-требования заложены в ТС — оба пути дешевле восстановления после падения.
Часто задаваемые вопросы
Вредит ли React SEO?
Нет – вредит любой фронтенд, отдающий пустой сырой HTML. В нашем кейсе падение вызвал самописный JavaScript-фреймворк без SSR, а React-версия с SSR как раз закрепила восстановление. Фреймворк – самописный, React или Vue – вторичный; первично то, что бот видит в HTML для выполнения скриптов.
Сколько Google рендерирует JavaScript?
Сканирование сырого HTML проходит сразу, а рендеринг JS стоит в отдельной очереди: Google документирует, что страница может ждать секунды, но может и дольше. Для каталога на тысячи SKU эта задержка умножается на каждую страницу – поэтому контент в сыром HTML более надежный.
У нас уже упал трафик после редизайна. Что делать сначала?
Снять страницы в сыром HTML без исполнения JS и сравнить с тем, что видит пользователь: ссылка, H1, текст, вес. Если бот видит пустоту – причина найдена, и она чинится. Параллельно проверить, сохранились ли URL, canonical и hreflang.
Когда вернется трафик после исправлений?
Google сроков переиндексации не документирует, поэтому честный ответ зависит от масштаба сайта и глубины проблемы. В этом кейсе контентный трек дал +20% за три месяца еще до SSR-релиза; эффект самого SSR оценивается через 4-6 недель после релиза по GSC.

Время вышло



