|
Professor Seleznov
|
В современной веб-разработке 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 не подошел Для начала нужно понять архитектурные особенности и структуру сайта. У нас есть:
- SSR;
- микрофронтенды, реализованные с помощью динамического Module Federation;
- каждый сервис находится в отдельном репозитории, разворачивается отдельно и подгружается только при непосредственном взаимодействии с ним (например, при переходе на страницу этого сервиса).
Основная причина отказа от SSR — обновление версии Angular с 12 до 17. В версиях 16–17 произошли крупные изменения, некоторые из них коснулись пакета для работы с SSR. Например, @nguniversal перестали поддерживать, а его функциональность перенесли в @angular/ssr Была попытка перейти на Nx (инструмент для сборки), но в нем не поддерживается Dynamic Module Federation и SSR одновременно. Это вызвало трудности с сохранением архитектуры и способствовало переходу к разделению рендеринга. Но раз чистый SSR отпал, нужно было искать альтернативу. И тут мы вспомнили про микрофронтенды — они тоже внесли свою лепту в сложность. Module Federation и 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 разработки;
- гарантировать хорошую индексацию.
Выбор сделан, решение принято. Осталось самое интересное — доработать открытый сервис под наши задачи. Что доработали в открытом решении (MTS botview) Основные доработки касались производительности и размеров требуемой памяти:
- Открытие внутреннего браузера один раз, а не для каждого запроса.
- Закрытие окон отрендеренных страниц после использования.
- Добавление метрик для мониторинга.
В результате мы сократили:
- время рендеринга страницы;
- объем памяти, который занимает рендеринг.
Это позволило обрабатывать больше запросов на том же железе и снизить задержки при индексации. Но как бы хорошо ни работал пререндеринг, важно не ошибиться с тем, кому его отдавать. Ведь если бот получит пустую страницу — пострадает 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 в микрофронтендовой архитектуре? Какие решения использовали и с какими трудностями встречались?-Источник
|