Стратегии и лучшие практики React SEO
Опубликовано: 2022-03-11React был разработан для создания интерактивных пользовательских интерфейсов, которые являются декларативными , модульными и кросс-платформенными . Сегодня это одна из самых популярных, если не самая популярная, среда JavaScript для написания производительных интерфейсных приложений. Первоначально разработанный для написания одностраничных приложений (SPA), React теперь используется для создания полноценных веб-сайтов и мобильных приложений.
Если у вас есть большой опыт в обычной веб-разработке и вы перешли на React, вы заметите, что все больше вашего кода HTML и CSS перемещается в JavaScript. Это связано с тем, что React не рекомендует напрямую создавать или обновлять элементы пользовательского интерфейса, а вместо этого описывает «состояние» пользовательского интерфейса. Затем React обновит DOM, чтобы наиболее эффективно соответствовать состоянию.
В результате все изменения в пользовательском интерфейсе или DOM должны производиться через движок React. Хотя это удобно для разработчиков, это может означать более длительное время загрузки для пользователей и дополнительную работу для поисковых систем по поиску и индексированию контента.
В этой статье мы рассмотрим проблемы, возникающие при создании SEO-эффективных приложений и веб-сайтов React, и обрисуем несколько стратегий, используемых для их преодоления.
Как Google сканирует и индексирует веб-страницы
Google получает более 90% всех онлайн-поисков. Давайте подробнее рассмотрим процесс сканирования и индексации.
Этот снимок, взятый из документации Google, может нам помочь. Обратите внимание, что это упрощенная блок-схема. Настоящий робот Googlebot гораздо сложнее.
Обратите внимание:
- Googlebot поддерживает очередь сканирования, содержащую все URL-адреса, необходимые для сканирования и индексации в будущем.
- Когда сканер бездействует, он выбирает следующий URL-адрес в очереди, делает запрос и извлекает HTML-код.
- После синтаксического анализа HTML робот Googlebot определяет, нужно ли ему получать и выполнять JavaScript для отображения содержимого. Если да, URL-адрес добавляется в очередь рендеринга.
- На более позднем этапе средство визуализации извлекает и выполняет JavaScript для отображения страницы. Он отправляет обработанный HTML обратно в процессор.
- Блок обработки извлекает все
<a> tags, упомянутые на веб-странице, и добавляет их обратно в очередь сканирования. - Контент добавляется в индекс Google.
Обратите внимание, что существует четкое различие между этапом обработки , который анализирует HTML, и этапом визуализации, который выполняет JavaScript.
Это различие связано с тем, что выполнение JavaScript обходится дорого , учитывая, что роботам Googlebot необходимо просматривать более 130 триллионов веб-страниц. Поэтому, когда робот Googlebot сканирует веб-страницу, он немедленно анализирует HTML-код, а затем ставит в очередь JavaScript для последующего запуска. В документации Google упоминается, что страница остается в очереди рендеринга на несколько секунд, хотя это может быть и дольше.
Также стоит упомянуть понятие краулингового бюджета. Сканирование Google ограничено пропускной способностью, временем и доступностью экземпляров Googlebot. Он выделяет определенный бюджет или ресурсы для индексации каждого веб-сайта. Если вы создаете большой ресурсоемкий веб-сайт с тысячами страниц (например, веб-сайт электронной коммерции), и эти страницы используют много JavaScript для отображения контента, Google может считывать меньше контента с вашего веб-сайта.
Примечание. С рекомендациями Google по управлению краулинговым бюджетом можно ознакомиться здесь.
Почему оптимизация React для SEO является сложной задачей
Наш краткий обзор робота Googlebot, сканирования и индексирования — это только поверхностные сведения. Тем не менее, инженеры-программисты должны выявлять потенциальные проблемы, с которыми сталкиваются поисковые системы, пытающиеся сканировать и индексировать страницы React. Теперь мы можем более подробно рассмотреть, что делает React SEO сложным, и что разработчики могут сделать, чтобы решить и преодолеть некоторые из этих проблем.
Пустой контент первого прохода
Мы знаем, что приложения React в значительной степени зависят от JavaScript, и у них часто возникают проблемы с поисковыми системами. Это связано с тем, что React по умолчанию использует модель оболочки приложения. Исходный HTML-код не содержит значимого содержимого, и пользователь или бот должны выполнить JavaScript, чтобы увидеть фактическое содержимое страницы.
Такой подход означает, что робот Googlebot обнаруживает пустую страницу при первом проходе. Контент виден Google только при отображении страницы. Это задержит индексацию контента при работе с тысячами страниц.
Время загрузки и пользовательский опыт
Извлечение, анализ и выполнение JavaScript требует времени. Кроме того, JavaScript может потребоваться выполнить сетевые вызовы для получения содержимого, а пользователю может потребоваться некоторое время подождать, прежде чем он сможет просмотреть запрошенную информацию.
Google изложил набор основных веб-показателей, связанных с пользовательским опытом, которые используются в его критериях ранжирования. Более длительное время загрузки может повлиять на оценку пользовательского опыта, что побудит Google ранжировать сайт ниже.
Мы подробно рассмотрим производительность веб-сайта в следующем разделе.
Метаданные страницы
Мета-теги <meta> полезны, потому что они позволяют Google и другим веб-сайтам социальных сетей отображать соответствующие заголовки, эскизы и описания страниц. Но эти веб-сайты полагаются на <head> выбранной веб-страницы для получения этой информации. Эти веб-сайты не выполняют JavaScript для целевой страницы.
React отображает весь контент, включая метатеги, на клиенте. Поскольку оболочка приложения одинакова для всего веб-сайта/приложения, может быть сложно адаптировать метаданные для отдельных страниц.
Карта сайта
Карта сайта — это файл, в котором вы предоставляете информацию о страницах, видео и других файлах на вашем сайте и взаимосвязях между ними. Поисковые системы, такие как Google, читают этот файл, чтобы более разумно сканировать ваш сайт.
В React нет встроенного способа создания карт сайта. Если вы используете что-то вроде React Router для управления маршрутизацией, вы можете найти инструменты, которые могут генерировать карту сайта, хотя это может потребовать некоторых усилий.
Другие соображения SEO
Эти соображения связаны с созданием хороших методов SEO в целом.
- Имейте оптимальную структуру URL, чтобы люди и поисковые системы имели представление о том, чего ожидать на странице.
- Оптимизация файла robots.txt может помочь поисковым роботам понять, как сканировать страницы вашего сайта.
- Используйте CDN для обслуживания всех статических ресурсов, таких как CSS, JS, шрифты и т. д., и используйте адаптивные изображения, чтобы сократить время загрузки.
Мы можем решить многие из проблем, описанных выше, используя рендеринг на стороне сервера (SSR) или предварительный рендеринг. Ниже мы рассмотрим эти подходы.
Войдите в изоморфную реакцию
Словарное определение изоморфности звучит так: «соответствует или похожа по форме».
В терминах React это означает, что сервер имеет такую же форму , что и клиент. Другими словами, вы можете повторно использовать одни и те же компоненты React на сервере и клиенте.
Этот изоморфный подход позволяет серверу отображать приложение React и отправлять обработанную версию нашим пользователям и поисковым системам, чтобы они могли мгновенно просматривать содержимое, пока JavaScript загружается и выполняется в фоновом режиме.
Такой подход популяризировали такие фреймворки, как Next.js или Gatsby. Следует отметить, что изоморфные компоненты могут существенно отличаться от обычных компонентов React. Например, они могут включать код, который выполняется на сервере, а не на клиенте. Они могут даже включать секреты API (хотя код сервера удаляется перед отправкой клиенту).
Следует отметить, что эти фреймворки абстрагируются от многих сложностей, но также вводят самоуверенный способ написания кода. Мы рассмотрим компромиссы производительности далее в этой статье.
Мы также проведем матричный анализ , чтобы понять взаимосвязь между путями рендеринга и производительностью веб-сайта. Но перед этим давайте рассмотрим некоторые основы измерения производительности веб-сайта.
Показатели производительности веб-сайта
Давайте рассмотрим некоторые факторы, которые поисковые системы используют для ранжирования веб-сайтов.
Google считает, что помимо быстрого и точного ответа на запрос пользователя, хороший веб-сайт должен обладать следующими характеристиками:
- Он должен загружаться быстро.
- Пользователи должны иметь возможность доступа к контенту без слишком длительного ожидания.
- Он должен стать интерактивным для действий пользователя на ранней стадии.
- Он не должен извлекать ненужные данные или выполнять дорогостоящий код, чтобы предотвратить разрядку пользовательских данных или батареи.
Эти функции примерно соответствуют следующим показателям:
- TTFB : время до первого байта — время между нажатием на ссылку и появлением первого бита контента.
- LCP : Самая крупная отрисовка контента — время, когда запрошенная статья становится видимой. Google рекомендует держать это значение менее 2,5 секунд.
- TTI : Time To Interactive — время, когда страница становится интерактивной (пользователь может прокручивать, щелкать и т. д.).
- Размер пакета — общее количество загруженных байтов и кода, выполненного до того, как страница станет полностью видимой и интерактивной.
Мы вернемся к этим показателям, чтобы лучше понять, как различные пути рендеринга могут повлиять на каждый из них.
Далее давайте разберемся с различными путями рендеринга, доступными разработчикам React.
Пути рендеринга
Мы можем визуализировать приложение React в браузере или на сервере и получать разные результаты.

Две функции значительно различаются между клиентскими и серверными приложениями, а именно: маршрутизация и разделение кода . Мы подробнее рассмотрим их ниже.
Рендеринг на стороне клиента (CSR)
Рендеринг на стороне клиента — это путь рендеринга по умолчанию для React SPA. Сервер будет обслуживать приложение-оболочку , не содержащее содержимого. Как только браузер загружает, анализирует и выполняет включенные источники JavaScript, HTML-контент заполняется или отображается .
Функция маршрутизации обрабатывается клиентским приложением путем управления историей браузера. Это означает, что один и тот же HTML-файл обслуживается независимо от того, какой маршрут был запрошен, и клиент обновляет свое состояние просмотра после его рендеринга.
Разделение кода относительно просто. Вы можете разделить свой код с помощью динамического импорта или React.lazy, чтобы загружались только необходимые зависимости на основе маршрута или действий пользователя.
Если странице необходимо получить данные с сервера для отображения контента — скажем, заголовка блога или описания продукта, — она может сделать это только тогда, когда соответствующие компоненты смонтированы и отрисованы.
Скорее всего, пользователь увидит знак или индикатор «Загрузка данных», пока веб-сайт загружает дополнительные данные.
Рендеринг на стороне клиента с загрузочными данными (CSRB)
Рассмотрим тот же сценарий, что и CSR, но вместо извлечения данных после рендеринга DOM предположим, что сервер отправил соответствующие данные, загруженные внутри обслуживаемого HTML.
Мы могли бы включить узел, который выглядит примерно так:
<script type="application/json"> {"title": "My blog title", "comments":["comment 1","comment 2"]} </script>И проанализируйте его, когда компонент монтируется:
var data = JSON.parse(document.getElementById('data').innerHTML);Мы только что сэкономили себе путь к серверу туда и обратно. Мы увидим компромиссы через некоторое время.
Рендеринг на стороне сервера в статическое содержимое (SSRS)
Представьте себе сценарий, в котором нам нужно генерировать HTML на лету.
Например, если мы создаем онлайн-калькулятор, и пользователь выдает запрос вида /calculate/34+15 (без экранирования URL). Нам нужно обработать запрос, оценить результат и ответить сгенерированным HTML.
Наш сгенерированный HTML довольно прост по структуре, и нам не нужен React для управления и манипулирования DOM после того, как сгенерированный HTML будет обработан.
Таким образом, мы просто обслуживаем содержимое HTML и CSS. Для этого можно использовать метод renderToStaticMarkup .
Маршрутизация будет полностью обрабатываться сервером, поскольку ему необходимо пересчитывать HTML для каждого результата, хотя кэширование CDN можно использовать для более быстрого обслуживания ответов. Файлы CSS также могут кэшироваться браузером для более быстрой загрузки последующих страниц.
Рендеринг на стороне сервера с регидратацией (SSRH)
Представьте тот же сценарий, что описан выше, но на этот раз нам нужно полнофункциональное приложение React на клиенте.
Мы собираемся выполнить первый рендеринг на сервере и отправить обратно HTML-контент вместе с файлами JavaScript. React повторно увлажнит разметку, отображаемую на сервере, и с этого момента приложение будет вести себя как приложение CSR.
React предоставляет встроенные методы для выполнения этих действий.
Первый запрос обрабатывается сервером, а последующие рендеры обрабатываются клиентом. Поэтому такие приложения называются универсальными приложениями React (отрисовываются как на сервере, так и на клиенте). Код для обработки маршрутизации может быть разделен (или дублирован) на клиенте и сервере.
Разделение кода также немного сложно, поскольку ReactDOMServer не поддерживает React. ленивы, поэтому вам, возможно, придется использовать что-то вроде загружаемых компонентов.
Следует также отметить, что ReactDOMServer выполняет только поверхностный рендеринг. Другими словами, хотя метод рендеринга для ваших компонентов будет вызываться, методы жизненного цикла, такие как componentDidMount , вызываться не будут. Поэтому вам нужно будет реорганизовать свой код, чтобы предоставить данные вашим компонентам, используя альтернативный метод.
Именно здесь появляются такие фреймворки, как NextJS. Они маскируют сложности, связанные с маршрутизацией и разделением кода в SSRH, и упрощают работу разработчиков.
Этот подход дает смешанные результаты, когда дело доходит до производительности страницы, как мы вскоре заметим.
Предварительный рендеринг статического контента (PRS)
Что, если бы мы могли отображать веб-страницу до того, как пользователь ее запросит? Это можно сделать во время сборки или динамически при изменении данных.
Затем мы можем кэшировать полученный HTML-контент в CDN и обслуживать его намного быстрее, когда пользователь запрашивает его.
Это называется предварительным рендерингом перед рендерингом контента, предварительным запросом пользователя. Этот подход можно использовать для блогов и приложений электронной коммерции, поскольку их содержание обычно не зависит от данных, предоставленных пользователем.
Предварительный рендеринг с регидратацией (PRH)
Мы можем захотеть, чтобы наш предварительно обработанный HTML был полностью функциональным приложением React, когда клиент его визуализирует.
После того, как первый запрос будет обслужен, приложение будет вести себя как стандартное приложение React. Этот режим аналогичен SSRH, описанному выше, с точки зрения функций маршрутизации и разделения кода.
Матрица производительности
Момент, которого вы так долго ждали, наконец настал. Пришло время для вскрытия. Давайте посмотрим, как каждый из этих путей рендеринга влияет на показатели веб-производительности, и определим победителя.
В этой матрице мы присваиваем оценку каждому пути рендеринга в зависимости от того, насколько хорошо он работает в метрике производительности.
Оценка варьируется от 1 до 5:
- 1 = неудовлетворительно
- 2 = плохо
- 3 = умеренный
- 4 = хорошо
- 5 = отлично
| ТТФБ Время до первого байта | ЛКП Самая большая содержательная краска | ТТИ Время интерактива | Размер пакета | Всего | |
|---|---|---|---|---|---|
| КСО | 5 HTML можно кэшировать в CDN | 1 Несколько обращений к серверу для получения HTML и данных | 2 Получение данных + задержки выполнения JS | 2 Все зависимости JS должны быть загружены перед рендерингом | 10 |
| CSRB | 4 HTML может кэшироваться, если он не зависит от данных запроса | 3 Данные загружаются с приложением | 3 JS должен быть извлечен, проанализирован и выполнен перед интерактивным | 2 Все зависимости JS должны быть загружены перед рендерингом | 12 |
| ССРС | 3 HTML генерируется при каждом запросе и не кэшируется | 5 Нет полезной нагрузки JS или асинхронных операций | 5 Страница становится интерактивной сразу после первой отрисовки | 5 Содержит только необходимый статический контент | 18 |
| ССРХ | 3 HTML генерируется при каждом запросе и не кэшируется | 4 Первый рендер будет быстрее, потому что сервер отрендерил первый проход | 2 Медленнее, потому что JS нужно гидратировать DOM после первого синтаксического анализа HTML + отрисовки | 1 Визуализированные зависимости HTML + JS должны быть загружены | 10 |
| сбн | 5 HTML кэшируется в CDN | 5 Нет полезной нагрузки JS или асинхронных операций | 5 Страница становится интерактивной сразу после первой отрисовки | 5 Содержит только необходимый статический контент | 20 |
| ПРХ | 5 HTML кэшируется в CDN | 4 Первый рендер будет быстрее, потому что сервер отрендерил первый проход | 2 Медленнее, потому что JS нужно гидратировать DOM после первого синтаксического анализа HTML + отрисовки | 1 Визуализированные зависимости HTML + JS должны быть загружены | 12 |
Ключевые выводы
Предварительный рендеринг статического контента (PRS) приводит к созданию наиболее эффективных веб- сайтов, в то время как рендеринг на стороне сервера с гидратацией (SSRH) или рендеринг на стороне клиента (CSR) может привести к неутешительным результатам.
Также можно использовать несколько подходов для разных частей веб-сайта . Например, эти показатели производительности могут иметь решающее значение для общедоступных веб-страниц, поэтому они могут быть проиндексированы более эффективно, в то время как они могут иметь меньшее значение после того, как пользователь вошел в систему и увидел данные частной учетной записи.
Каждый путь рендеринга представляет собой компромисс в том, где и как вы хотите обрабатывать свои данные. Важно то, что команда инженеров может четко увидеть и обсудить эти компромиссы и выбрать архитектуру, которая максимально удовлетворит их пользователей.
Дальнейшее чтение и соображения
Хотя я пытался охватить популярные в настоящее время методы, это не исчерпывающий анализ. Я настоятельно рекомендую прочитать эту статью, в которой разработчики из Google обсуждают другие передовые методы, такие как рендеринг на потоковом сервере, трисоморфный рендеринг и динамический рендеринг (предоставление разных ответов поисковым роботам и пользователям).
Некоторые другие факторы, которые необходимо учитывать при создании веб-сайтов с большим количеством контента, включают потребность в хорошей системе управления контентом (CMS) для ваших авторов, а также возможность легко создавать/модифицировать предварительные просмотры в социальных сетях и оптимизировать изображения для различных размеров экрана.
