SSR и CSR в одном месте: как мы разделили рендеринг для людей и поисковых ботов
- четверг, 21 мая 2026 г. в 00:00:12
В современной веб-разработке SEO и производительность часто вступают в противоречие. SSR дает хорошую индексацию, но усложняет архитектуру. CSR быстрее в разработке и меньше нагружает сервер, но поисковые боты могут не понять страницу.
Мы разрабатываем продуктовый сайт на Angular 17 с микрофронтендовой архитектурой на Module Federation. Нам нужно было и хорошее SEO, и привычный CSR для пользователей. В итоге мы выбрали гибридный подход: для людей — клиентский рендеринг, для поисковых ботов — пререндеринг через доработанный сервис MTS botview.
В статье рассказываем, почему чистый SSR не подошел, как мы разделили рендеринг, что доработали в открытом решении и как отличаем ботов от людей без ошибок.
Для начала поясним, что такое SSR и CSR:
SSR (Server-Side Rendering) — метод рендеринга веб-страницы на сервере, где сервер отдает уже полностью сформированную HTML-страницу.
CSR (Client-Side Rendering) — метод рендеринга, при котором основной контент формируется непосредственно в браузере, а сервер отдает минимальный HTML-шаблон.
Сайт написан на Angular 17 с использованием микрофронтендовой архитектуры, которая реализована с помощью Module Federation из пакета @angular-architects. Это продуктовый сайт, поэтому для него важно быть в топе поисковой выдачи — то есть иметь хорошее SEO.
Изначально на сайте был реализован SSR, который позволяет отдавать браузеру практически готовый HTML-файл со структурным содержимым (тексты, ссылки, картинки). Это положительно влияет на SEO.
Однако в связи с архитектурными и техническими особенностями не было возможности сделать чистый SSR, который предлагает Angular «из коробки».
Для начала нужно понять архитектурные особенности и структуру сайта. У нас есть:
SSR;
микрофронтенды, реализованные с помощью динамического Module Federation;
каждый сервис находится в отдельном репозитории, разворачивается отдельно и подгружается только при непосредственном взаимодействии с ним (например, при переходе на страницу этого сервиса).
Основная причина отказа от SSR — обновление версии Angular с 12 до 17. В версиях 16–17 произошли крупные изменения, некоторые из них коснулись пакета для работы с SSR. Например, @nguniversal перестали поддерживать, а его функциональность перенесли в @angular/ssr
Была попытка перейти на Nx (инструмент для сборки), но в нем не поддерживается Dynamic Module Federation и SSR одновременно. Это вызвало трудности с сохранением архитектуры и способствовало переходу к разделению рендеринга.
Но раз чистый SSR отпал, нужно было искать альтернативу. И тут мы вспомнили про микрофронтенды — они тоже внесли свою лепту в сложность.
Изначально реализация строилась на двух библиотеках:
@nguniversal/common — для SSR;
@angular-architects/module-federation — для Module Federation.
Соединить их в единую работающую схему оказалось нетривиальной задачей. Dynamic Module Federation подразумевает подгрузку модулей по требованию, а SSR в Nx требует, чтобы все маршруты и компоненты были известны на сервере заранее. Эти два подхода вступают в противоречие, что и стало одной из ключевых причин поиска альтернативы.
В итоге мы поняли: нужно либо полностью переписывать архитектуру, либо искать обходной путь. Мы выбрали второй вариант.
Мы выбрали подход с разделением рендеринга для клиентов и поисковых ботов:
Для клиентов работает обычный CSR. Браузер получает практически пустую HTML-страницу, а уже при исполнении скриптов она наполняется контентом.
Для поисковых ботов реализован пререндеринг с помощью сервиса МТС botview, который позволяет отрендерить страницу перед отдачей ее боту.
Мы доработали открытое решение (увеличили производительность и скорость рендеринга, оптимизировали занимаемую память) и внедрили его в веб-сайт.
Как это работает: сервер по заголовку User-Agent определяет, кто запрашивает страницу — клиент или поисковый бот, — и перенаправляет исполнение на соответствующий сервис.
Логичный вопрос: а почему мы вообще решили, что для людей можно оставить CSR, а для ботов делать отдельный пререндеринг? Давайте сравним подходы.
Если сравнивать CSR и SSR, ключевые различия выглядят так:
Характеристика | CSR | SSR |
Скорость первоначальной загрузки | Ниже (ждем скрипты) | Выше (готовый HTML) |
TBT (Total Blocking Time) | Выше | Ниже |
Нагрузка на сервер | Ниже | Выше |
SEO | Хуже | Лучше |
Удобство для SPA | Привычнее | Сложнее |
Проанализировав преимущества и недостатки двух подходов, мы решили для людей оставить простой CSR, а SEO-требования закрыть через пререндеринг для ботов. Это позволило:
не переписывать архитектуру под чистый SSR;
сохранить привычный CSR разработки;
гарантировать хорошую индексацию.
Выбор сделан, решение принято. Осталось самое интересное — доработать открытый сервис под наши задачи.
Основные доработки касались производительности и размеров требуемой памяти:
Открытие внутреннего браузера один раз, а не для каждого запроса.
Закрытие окон отрендеренных страниц после использования.
Добавление метрик для мониторинга.
В результате мы сократили:
время рендеринга страницы;
объем памяти, который занимает рендеринг.
Это позволило обрабатывать больше запросов на том же железе и снизить задержки при индексации.
Но как бы хорошо ни работал пререндеринг, важно не ошибиться с тем, кому его отдавать. Ведь если бот получит пустую страницу — пострадает SEO. А если человек попадет на пререндеренную страницу — ничего страшного, но все же…
Основной способ различить людей и ботов — заголовок User-Agent:
Для клиентов там обычно прописывается специфика браузера и устройства (Chrome, Firefox, Safari и т.д.).
Для ботов существует список известных значений: Googlebot, YandexBot, Bingbot и другие.
Что будет, если ошибемся?
Если человек попадет на пререндеринг — ничего страшного. Страница также загрузится, и пользователь сможет с ней взаимодействовать (просто получит готовый HTML вместо пустого шаблона).
Если поисковый бот получит непререндеренную страницу (CSR) — он может ее не распарсить и не понять, что на ней находится. Это приведет к падению позиций в выдаче.
Поэтому важно поддерживать актуальный список User-Agent для ботов и мониторить, не появляются ли новые.
Прежде чем остановиться на MTS botview, мы, конечно, рассматривали и другие варианты. Коротко расскажем, почему выбор пал именно на него.
Мы пытались все-таки остаться в рамках чистого SSR + Dynamic Module Federation + раздельные репозитории. Но чтобы добиться хоть какого-то рабочего варианта, потребовалось бы много времени (которого у нас не было), и это был бы очень тяжелый технический вызов.
Почему выбрали именно MTS botview:
сервис оказался в открытом доступе;
он достаточно прост для понимания и доработок;
его можно было адаптировать под наши задачи без переписывания с нуля.
Альтернативы (например, самостоятельная реализация headless-браузера или сторонние коммерческие сервисы) требовали либо больших затрат на разработку, либо дополнительного бюджета и интеграции.
В результате мы получили работающее решение, которое сочетает:
привычный CSR для пользователей (быстрая разработка, низкая нагрузка на сервер);
качественный пререндеринг для поисковых ботов (хорошее SEO);
минимальные доработки открытого сервиса вместо тяжелого рефакторинга архитектуры.
Такой гибридный подход позволил нам сохранить микрофронтендовую архитектуру на Module Federation, не жертвовать производительностью для пользователей и при этом обеспечить полную индексацию сайта поисковыми системами.
А вы сталкивались с необходимостью совмещать SSR и CSR в микрофронтендовой архитектуре? Какие решения использовали и с какими трудностями встречались?