Как известно, поисковая оптимизация одностраничных приложений задача непростая и решение ее может потребовать значительных затрат труда, особых умений от разработчиков и финансовых затрат от заказчика. Какие же решения предлагает сообщество, чтобы, по возможности быстро и с минимальными затратами, сделать React веб-сайт дружественным к поисковым серверам?

Немного банальностей о SEO


Около 92% трафика приходит с первой страницы результатов запроса поискового сервера, причем 75% трафика приходится на первые пять веб-сайтов.
Google занимает более 90% рынка поисковых серверов.
Search Engine Optimization (SEO) — это процесс структуризации и организации сайта с целью увеличения объема и повышения качества его трафика путем повышения его положения и частоты появления в результатах поисковых серверов, фокусируясь на ключевых словах раскрывающих специфику сайта.
Главная цель SEO процесса — улучшать заметность сайта в интернете и увеличивать трафик сайта.


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


Это может показаться довольно простым, но, в случае сайтов построенных на React, это не всегда так.


React и SEO


Кратко о SPA


Одностраничное приложение или SPA — это веб приложение или веб-сайт, который взаимодействует с пользователем посредством динамического изменения текущей страниц, а не загрузки новых страниц с сервера. SPA работают быстро, т.к. большинство ресурсов (HTML+CSS+Scripts) загружаются только однажды на протяжении всего периода их жизни. Приложение получает и отдает только данные.
Одним из примеров технологии, которая может использоваться для создания SPA, является ReactJS, библиотека, которая хорошо оптимизирована для работы на пользовательских браузерах (больше здесь.)


Основные проблемы SPA с SEO


SPA — это, по сути, JavaScript-программа работающая в браузере и если поисковый веб-бот не умеет исполнять скрипты, он не сможет получить правильно отрендеренную страницу и ее проиндексировать.

Google в октябре 2015 года сделал важное объявление о том, что его боты будут запускать JS файлы на веб-сайтах в случае предоставления им прав делать это. И, хотя это заявление звучит очень позитивно, а сами его поисковые боты становятся более совершенными, полагаться на их способность выполнять JavaScript рискованно. Google бот может отказаться от выполнения JavaScript по множеству причин (подробнее здесь):


  • несоблюдения п��авила «золотых 5 сек» (подробнее здесь и здесь);
  • невозможности сканирования сайта: системы Google должны быть способны просканировать сайт, учитывая его структуру (подробнее здесь);
  • невозможности анализа сайта: системы Google не должны испытывать проблем в ходе анализа сайта с использованием технологий, используемых для формирования его страниц (подробнее здесь);
  • ошибок в коде и пр.

Боты других поисковых серверов, таких как Yahoo, Bing, Baidu и др. не поддерживают JavaScript и видят страницы SPA пустыми.


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


Решения проблемы SEO для SPA веб-сайтов


Имется два главных способа решения SEO проблем стоящих перед SPA веб-сайтами:

  1. Изоморфный (универсальный) SPA;
  2. Пререндеринг.

Дополнительные средства улучшения SEO для React веб-сайтов:

  • React Router v4: компонент для создания дружественных к SEO «rout»-ов в React приложениях;
  • React Helmet: едва ли не самый важный компонент для обеспечения SEO React-приложений, дающий возможность управлять meta-тегами приложения и отличающийся простотой применения.

Как изоморфный React помогает с SEO?


Изоморфный React сайт автоматически определяет, отключен ли JavaScript на стороне клиента. Если JavaScript отключен, скрипт выполняется на сервере и результат (статический HTML+CSS) отсылается клиенту. В этом случае все необходимые для SEO атрибуты и контент присутствуют во время загрузки.
Если же JavaScript включен, изоморфный React сайт в простейшем случае может загружаться обычным образом, когда все рендерится в браузере, либо ухищренно: выполняется частичный рендеринг на стороне сервера, что значит, что только первый DOM рендеринг производится на сервере, а все последующие производятся непосредственно в браузере. Другими словами, браузер получает полностью отрендеренную первоначальную DOM и JavaScript, а когда состояние приложения изменяется — отвечает за все последующие обновления.


Считается, что изоморфное решение является лучшим методом решения SEO проблем SPA веб-приложений, но незадача, к сожалению, в том, что подобные решения для React SPA, на сегодняшний момент, трудно реализуемы:


  • популярные React бойлерплейты, например create-react-app, react-boilerplate не поддерживают изоморфность. Dan Abramov, разработчик create-react-app:
    В конечном итоге рендеринг на стороне сервера очень сложно добавить значимым образом, не принимая также ответственных решений. На данный момент мы не собираемся принимать такие решения;
  • существующие изоморфные бойлерплейты сложны в освоении;
  • существующие решения несовершенны:
    • зачастую код на сервере и на клиенте имеет много различий;
    • в случае практически полного совпадения кодовой базы, код становится медленным и склонным к сбоям.

    Похоже, многие разработчики поддержат мнение высказанное MrCheater в обсуждении статьи «Изоморфные React-приложения: производительность и масштабирование»:

    У темы «изоморфных веб-приложений» много ненавистников. Увы. Хотя легко понять почему, всё очень сложно программируется, сотни статей на эту тему, а на выходе всё равно у всех получается страшный клиент весом 3 мегабайта. Но когда-нибудь скоро все проблемы и подходы к их решению будут стандартизированы, и мы будем иметь легковесные изоморфные single page application.

    Решение проблемы SEO посредством пререндеринга


    Пререндеринг — это процесс предварительного рендеринга страниц веб-сайта с целью подготовки их к просмотру поисковым веб-ботом. Пререндер-сервис перехватывает запросы к веб-сайту, по «user-agent» запроса определяет тип клиента, и если запрос был сделан веб-ботом, сервис отсылает обратно предварительно отрендеренную кешированную статическую версию сайта. Если же запрос был сделан не поисковым веб-ботом, загружается обычная страница. Пререндеринг используется только для оптимизации работы с веб-ботами и, возможно, с устаревшими браузерами. Пререндер-сервисы, например Рrerender.cloud и ему подобные, используют «headless» браузеры, чаще всего Headless Chrome. Такой подход позволяет использовать для построения веб-сайта самые новые JavaScript фреймворки типа React, Ember, и Angular и не полагаться на серверный рендеринг.


    Достоинства пререндеринга:


    • пререндер способен выполнять все типы современного JavaScript и выдает статический HTML;
    • пререндер поддерживает самые последние веб-нововведения;
    • требуется минимальная модификация кодовой базы веб-приложения, если вообще таковая потребуется;
    • снижаются затраты на разработку и поддержку веб-сайта;
    • простота имплементации.

    Недостатки пререндеринга:

    • мало пригоден для страниц, которые отображают часто изменяющиеся данные;
    • не приемлем для страниц, которые содержат персональные данные пользователей. Впрочем, такие страницы мало полезны для SEO и не должны индексироваться;
    • в случае большого сайта со значительным количеством страниц, процесс пререндеринга можеть занимать значительное время;
    • пререндер-сервисы платные.

    Пререндеры, где их взять


    Сообщество разработало значительное количество пререндеров: см., например, здесь.


    Среди многих вариантов ��редставляется интересным OpenSource Prerenderопенсорсная версия пререндера используемого на сервисе prerender.io, которую можно имплементировать на собственном сервере поддерживающем Node.js.


    Еще один, интересный тем, что не требует наличия сервера, пререндер — Prerender SPA Plugin, который подключается путем простой модификации webpack.config.js, например к create-react-app или react-boilerplate. Процесс пререндеринга выполняется в процессе «билдинга» сайта и результат помещается в index.html.


    Можно воспользоваться и готовыми сервисами предоставляющими услуги пререндеринга, перечень некоторых приведен здесь и здесь.


    Здесь можно ознакомиться также и с практическим опытом работы с пререндерами.


    Особенно интересным представляется сервис Roast.io, предоставляющий услуги как CDN, так и пререндеринга (!). Сервис также автоматически (если таковые отсутствуют) добавляет «screenshot link unfurls» мета-теги, улучшающие отображение веб-сайта в в социальных сетях.
    Сервис расположен на AWS CDN, работает по HTTPS протоколу, настроен под SPA и React в частности, очень прост в использовании. Имеется опция бесплатного хостинга (10GB bandwidth, 500 pages SSR).


    Итак:


    Пререндеринг, будучи не идеальным решением, выглядит более предпочтительным для значительной части разработчиков React-приложений в силу того, что:
    • не требуется доработка кода приложения — можно без опасений использовать свой любимый бойлерплейт;
    • наличествует широкий выбор реализаций — «middleware», «webpack», «CDN+prerender», «opensource» и платных;
    • внедрение пререндеринга — простой процесс, особенно в случае «CDN+prerender» реализаций;
    • имеется серьезная поддержка со стороны Google в виде Headless Chrome;
    • уменьшаются затраты на разработку и поддержку приложения;
    • имеются опции бесплатного использования пререндер-веб-сервисов.

    Однако, нужно подумать об изоморфном (универсальном) варианте сайта, если:
    • веб-приложение отображает часто изменяющиеся данные;
    • веб-приложение содержит сотни страниц, ведь процесс пререндеринга можеть занять значительное время.

    Если же веб-сайт содержит только статические страницы (HTML+CSS), то ни изоморфность, ни преререндеринг не требуются.