JavaScript SEO: все, что нужно знать

Patrick Stox
Патрик Стокс — консультант по продукту, технический SEO-специалист и амбассадор бренда в Ahrefs. Он является организатором Raleigh SEO Meetup, конференции Raleigh SEO, Beer & SEO Meetup, конференции Findability и модератором /r/TechSEO.
    Знаете ли вы, что блог Ahrefs размещен на WordPress, а большая часть остального сайта работает на JavaScript-библиотеке React?

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

    Как сказал Джон Мюллер из Google:

    Я не говорю, что специалистам SEO нужно идти учиться программированию на JavaScript. Наоборот. Специалистам SEO нужно знать, как Google обрабатывает JavaScript и как устранять неполадки. Редко когда специалисту SEO разрешат даже притронуться к коду. Цель этого поста — познакомить вас с основами.

    SEO для JavaScript относится к техническому SEO (Search Engine Optimization — оптимизация для поисковых систем). Цель такой оптимизации — сделать веб-сайты с большим количеством JavaScript более удобными для сканирования и индексирования, а также оптимизированными для поисковых систем. Это делается для того, чтобы эти веб-сайты можно было найти и высоко ранжировать в поисковых системах.

    JavaScript вредит SEO? JavaScript — это зло? Вовсе нет. Он просто отличается от того, к чему привыкли большинство специалистов SEO, и требует накопления некоторого опыта. Часто его используют избыточно вместо того, чтобы найти более подходящее решение, но иногда приходится иметь дело с тем, что есть. Помните, что JavaScript не совершенен и не является универсальным инструментом. В отличие от HTML и CSS, его нельзя последовательно анализировать. Он также может требовать больших ресурсов, что влияет на скорость загрузки и производительность страницы. Во многих случаях вам придется жертвовать производительностью ради функциональности.

    На заре поисковых систем, чтобы увидеть контент большинства страниц, было достаточно загрузить ответ в HTML. С распространением JavaScript, поисковым системам теперь необходимо рендерить множество страниц, как это делает браузер, чтобы увидеть контент так, как его видит пользователь.

    Система, которая осуществляет рендеринг в Google, называется “Сервис обработки веб-страниц” (Web Rendering Service, WRS). Google предоставил упрощенную схему этого процесса.

    Допустим, процесс начинается с URL-адреса.

    1. Краулер

    Краулер посылает GET-запросы на сервер. Сервер отвечает, предоставляя заголовки и содержимое файла, которые затем сохраняются.

    Запрос скорее всего поступает от агента пользователя на мобильном устройстве, поскольку Google теперь преимущественно приоритизирует контент для мобильных устройств при индексировании. Вы можете проверить, как Google сканирует ваш сайт с помощью инструмента “Проверка URL в Search Console. После ввода URL-адреса посмотрите информацию в отчете “Покрытие” в графе “Робот, выполнивший сканирование”. Здесь будет отражено, остались ли вы на индексировании для компьютеров или перешли на индексацию для мобильных устройств.

    image6

    Запросы приходят в основном из Маунтин-Вью, Калифорния, США, однако некоторые запросы поступают в рамках сканирования страниц с определением локали из-за пределов США. Я это упоминаю, потому что некоторые сайты могут по-разному реагировать на пользователей, использующих определенный IP или находящихся в конкретной стране (например, блокировать их), из-за чего ваш контент может быть недоступен Googlebot.

    Некоторые сайты могут также определять агент пользователя, чтобы показывать контент для определенного краулера. Особенно это актуально для сайтов на JavaScript, на которых Google и пользователь могут видеть абсолютно разный контент. Вот почему для устранения неполадок SEO, связанных с JavaScript, так важны инструменты Google, в том числе инструмент проверки URL в Google Search Console, Проверка оптимизации для мобильных и Проверка расширенных результатов. Они показывают вам то, что видит Google, и помогают в проверки возможной блокировки Google и возможности просмотра контента страницы. Я расскажу о том, как это проверить, в разделе о рендерере, поскольку между загрузкой с помощью GET-запроса, выводимой страницей и даже инструментами тестирования есть существенные отличия.

    Также важно отметить, что хоть на рисунке выше Google и утверждает, что результатом процесса сканирования является HTML, в реальности они сканируют и сохраняют все ресурсы, необходимые для построения страницы. HTML-страницы, файлы JavaScript, CSS, запросы XHR, конечные точки API и т. д.

    2. Обработка

    Под термином “Обработка” на рисунке замаскировано множество систем. Я расскажу о некоторых из них, релевантных для JavaScript.

    Ресурсы и ссылки

    Google не переходит со страницы на страницу, как это делает пользователь. Частью обработки является проверка страницы на наличие ссылок на другие страницы и файлы, необходимые для ее построения. Эти ссылки собираются и добавляются в очередь сканирования, которую Google использует для приоритизации и планирования сканирования.

    Google собирает ссылки на ресурсы (CSS, JS и др.), необходимые для построения страницы, из подобных элементов: <link> теги. Тем не менее ссылки на другие страницы должны иметь определенный формат, чтобы Google посчитал их ссылками. Внутренние и внешние ссылки должны быть тегом <a> с атрибутом href. Существует множество способов сделать так, чтобы это сработало для пользователей с JavaScript без оптимизации для поиска.

    Хорошо:

    <a href=”/page”>просто и хорошо</a>
    <a href=”/page” onclick=”goTo(‘page’)”>терпимо</a>

    Плохо:

    <a onclick=”goTo(‘page’)”>нет, отсутствует href</a>
    <a href=”javascript:goTo(‘page’)”>нет, отсутствует ссылка</a>
    <a href=”javascript:void(0)”>нет, отсутствует ссылка</a>
    <span onclick=”goTo(‘page’)”>неправильный элемент HTML</span>
    <option value="page">нет, ошибочный элемент HTML</option>
    <a href=”#”>отсутствует ссылка</a>
    Кнопка, директива ng-click — существует еще много неправильных способов.

    Также стоит отметить, что внутренние ссылки, добавленные с помощью JavaScript, не будут собираться до рендеринга. В большинстве случаев это происходит довольно быстро и не представляет проблемы.

    Кэширование

    Каждый загружаемый Google файл, включая HTML-страницы, файлы JavaScript, файлы CSS и т. д., будет агрессивно кэширован. Google проигнорирует ваши настройки кэширования и просканирует новую версию, когда сам захочет. Я еще немного расскажу об этом и почему это важно в разделе про рендерер.

    Исключение дубликатов

    Дублированный контент может быть исключен или лишен приоритизации из загруженного HTML перед отправкой на рендеринг. С помощью моделей оболочек приложений в ответе HTML может быть показана совсем небольшая часть контента и кода. Фактически каждая страница на сайте может показывать один и тот же код, и этот же код может повторяться на нескольких веб-сайтах. Это может привести к тому, что страницы будут считаться дублирующими и будут рендериться не сразу. И даже хуже, в результатах поиска может отображаться неправильная страница или неправильный сайт. Скорее всего это саморазрешится со временем, но такое поведение может быть проблемным, особенно для более новых веб-сайтов.

    Самые строгие директивы

    Google выберет наиболее строгие операторы между HTML и выводимой версией страницы. Если JavaScript меняет оператор, что приводит к конфликту с оператором в HTML, то Google воспользуется более строгим из них. У noindex будет приоритет перед index, и noindex в HTML не допустит рендеринга в целом.

    3. Очередь рендеринга

    Теперь каждая страница передается на рендеринг. Одной из самых больших трудностей, с которыми сталкиваются большинство SEO-специалистов при работе с JavaScript и двухэтапным индексированием (HTML, затем рендеринг страницы), является то, что страницы могут не рендериться днями или даже неделями. Когда Google исследовали этот вопрос, они выяснили, что страницы передаются рендереру в среднем за 5 секунд, или за минуты в 90 процентиле. Так что о времени между получением HTML и рендерингом страницы в большинстве случаев можно не беспокоиться.

    4. Рендерер

    Рендерер — это среда, в которой Google рендерит страницу, чтобы увидеть ее глазами пользователя. Именно здесь он будет обрабатывать JavaScript и любые изменения, внесенные с помощью JavaScript в объектную модель документа (DOM).

    Для этого Google использует консольную версию браузера Chrome, которая теперь “всегда актуальная”, то есть использует последнюю версию Chrome и поддерживает его последние функций. До недавнего времени Google использовали для рендеринга Chrome 41, так что многие функции не поддерживались.

    У Google больше информации о сервисе обработки страниц (Web Rendering Service, WRS), в том числе об отказе в разрешениях, пребывании без сведений о состоянии, развернутое дерево Light DOM и Shadow DOM и многое другое, о чем стоит прочитать.

    Рендеринг в масштабах сети может быть 8 чудом света. Это серьезное дело, и оно занимает огромное количество ресурсов. Из-за огромного масштаба Google прибегает ко множеству хитростей для ускорения рендеринга. Ahrefs является единственным инструментом SEO, который масштабно рендерит веб-страницы — мы рендерим 150 миллионов страниц в день, чтобы наш индекс ссылок был более полным. Это позволяет нам не только проверять редиректы JavaScript, но и показывать ссылки, которые были вставлены с помощью JavaScript. В отчетах по ссылкам их можно узнать по тегу JS.

    image3

    Кэшированные ресурсы

    Google сильно зависит от кэшированных ресурсов. Страницы, файлы, запросы API — перед отправкой на рендеринг кэшируется фактически все. Во время рендеринга они не загружают каждый раз заново все ресурсы страницы, а используют кэшированные ресурсы, чтобы ускорить процесс.

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

    Нет фиксированного времени ожидания

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

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

    Что видит Googlebot

    Googlebot ничего не предпринимает на веб-страницах. Он не кликает по объектам и не прокручивает экран, но это не значит, что у него нет обходных путей. Что касается контента, то пока он загружается в DOM без необходимости производить каких-либо действий, его будет видно. Я немного больше это раскрою в разделе устранения неполадок, но по сути, если контент находится в DOM и просто спрятан, то его увидят. Если он не загружается в DOM до клика, тогда контент не будет найден.

    Google также не нужно прокручивать страницу, чтобы увидеть ваш контент, потому что у него есть умный обходной путь, позволяющий видеть контент. Для мобильных устройств он загружает страницу в разрешении экрана 411x731 пикселей и увеличивает его высоту до 12 140 пикселей. Получается очень длинный телефон с размером экрана 411x12140 пикселей. Для компьютеров он делает то же самое и изменяет размер страницы с 1024x768 пикселей на 1024x9307 пикселей.

    Еще один интересный обходной путь Google в том, что он не отрисовывает пиксели во время рендеринга. Завершение загрузки страницы требует дополнительного времени и вычислительных ресурсов, а Google на самом деле не нужно видеть конечное состояние страницы со всеми отрисованными пикселями. Ему нужно знать только структуру и разметку, и он их получает без необходимости отрисовывать пиксели по-настоящему. Вот, что об этом говорит Мартин Сплитт из Google:

    https://youtube.com/watch?v=Qxd_d9m9vzo%3Fstart%3D154

    В поиске Google мы на самом деле не очень заботимся о пикселях, потому что нам не нужно это кому-то показывать. Мы хотим обрабатывать информацию и семантические данные, так что нам достаточно переходного состояния. Нам не нужно отрисовывать пиксели.

    Иллюстрация поможет лучше объяснить, что именно отсекается. В инструментах разработчика Chrome, если вы запустите тест на вкладке Performance, получите график загрузки. Стадия отрисовки представлена в графике сплошным зеленым цветом, а для Googlebot этого никогда не происходит, так что они экономят ресурсы.

    image2

    Серый = загрузки

    Синий = HTML

    Желтый = JavaScript

    Пурпурный = Макет

    Зеленый = Отрисовка

    5. Очередь сканирования

    У Google есть ресурс, который немного рассказывает о краулинговом бюджете, но вам стоит знать, что у каждого сайта есть собственный краулинговый бюджет, и каждый запрос нужно приоритизировать. Google также необходимо сбалансировать сканирование вашего сайта и всех остальных сайтов в Интернете. Новые сайты или сайты с множеством динамичных страниц скорее всего будут просканированы медленней. Некоторые страницы будут обновляться реже, чем другие, а некоторые ресурсы могут запрашиваться менее часто.

    Одна из хитростей с сайтами на JavaScript заключается в том, что они могут обновлять только часть DOM. Переход на другую страницу в качестве пользователя может не обновить некоторые аспекты, такие как теги title или канонические теги в DOM, но это не будет проблемой для поисковых систем. Помните, Google загружает каждую страницу без сведений о состоянии, поэтому он не сохраняет предыдущую информацию и не осуществляет навигацию между страницами. Это запутывает некоторых SEO-специалистов и они начинают думать, что существует проблема из-за того, что они увидели при переходе с одной страницы на другую, например, если не обновился канонический тег, но Google может никогда этого не увидеть. Разработчики могут это исправить, обновив состояние с помощью History API, но опять-таки это может и не быть проблемой. Обновите страницу, и вы увидите то, что видит пользователь, а еще лучше проверьте ее с помощью одного из инструментов тестирования Google, чтобы увидеть то, что видят они. Подробнее об этом через пару секунд.

    Команды “Просмотр кода страницы” и “Просмотреть код”

    Если вы кликните правой кнопкой мышки в окне браузера, то видите пару команд: “Просмотр кода страницы” (View source) и “Просмотреть код” (Inspect). Команда “Просмотр кода страницы” покажет вам то же, что вы увидите в GET-запросе. Непосредственный HTML страницы. Команда “Просмотреть код” покажет вам обработанный DOM после внесения изменений. Это ближе к тому контенту, который видит Googlebot. По сути это обновленная и последняя версия страницы. Лучше использовать команду “Просмотреть код” вместо команды “Просмотр кода страницы”, когда работаете с JavaScript.

    image1

    Кэш Google

    Кэш Google не является надежным способом проверки того, что видит Googlebot. Обычно он показывает исходный HTML, но иногда может показать рендер HTML или более старую версию. Система устроена так, чтобы предоставлять контент, когда веб-сайт не работает. Она не особо полезна в качестве инструмента отладки.

    Инструменты тестирования Google

    Инструменты тестирования Google, такие как “Проверка URL” в Google Search Console, “Проверка оптимизации для мобильных” или “Проверка расширенных результатов”, полезны для отладки. Но даже эти инструменты не дают абсолютно ту же картину, которую видит Google. Я уже говорил о времени ожидания в пять секунд в этих инструментах, которого нет у рендерера. У этих инструментов есть еще одно отличие — они вытягивают ресурсы в реальном времени и не используют кэшированные версии, как это делает рендерер. Снимки экранов в этих инструментах также показывают страницы с отрисованными пикселями, что Google не видит в рендерере.

    И все же эти инструменты помогут узнать загружается ли контент из DOM. HTML, который показывают эти инструменты, является рендером DOM. Вы можете искать фрагмент текста, чтобы посмотреть, был ли он загружен по умолчанию.

    image10

    Инструменты также покажут вам ресурсы, которые могут быть заблокированы и сообщения об ошибкам консоли, полезные для отладки.

    Поиск текста в Google

    Другой способ быстро проверить страницу — просто поискать фрагмент вашего контента в Google. Введите в поиск “какую-нибудь фразу из вашего контента” и посмотрите выдается ли по ней страница. Если да, то скорее всего ваш контент виден. Обратите внимание, что спрятанный по умолчанию контент может не обнаруживаться в выдаче.

    Ahrefs

    Вместе с ссылочным индексом рендеринга страниц вы можете включить поддержку JavaScript в сканировании Аудита сайта, чтобы разблокировать больше данных в ваших аудитах.

    image5

    Тулбар Ahrefs тоже поддерживает JavaScript и позволяет вам сравнить HTML с выводимыми версиями тегов.

    image8

    Существует множество вариантов рендеринга JavaScript. У Google есть солидная диаграмма, которую я хочу вам показать. Для поисковых систем подойдет любой вид SSR, статичный рендеринг или установка пререндеринга. Основной причиной возникновения проблем являются ситуации, в которых рендеринг полностью выполняется на стороне клиента, в браузере.

    И хотя Google, вероятно, справится даже с рендерингом на стороне клиента, лучше выбрать другой вариант, поддерживаемый и другими поисковыми системами. Bing также поддерживает рендеринг JavaScript, но в неизвестных масштабах. В Яндексе и Baidu, из того, что я видел, поддержка ограничена, а многие другие поисковые системы почти или вовсе не поддерживают JavaScript.

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

    Обратите внимание, что стараясхема сканирования AJAX не рекомендуется к использованию и больше не поддерживается.

    Многие процессы похожи на то, к чему привыкли SEO-специалисты, за некоторыми отличиями.

    On-page SEO

    Применимы все обычные правила по on-page SEO для контента, теги title и meta description, атрибуты alt, теги meta robot и прочее. См. On-Page SEO: руководство к действию.

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

    Разрешите сканирование

    Не блокируйте доступ к ресурсам. Google необходимо получать доступ к ресурсам и загружать их, чтобы корректно выполнять рендеринг страниц. Самым простым способом разрешить сканирование необходимых ресурсов будет добавление в robots.txt следующего кода.

    User-agent: Googlebot
    Allow: .js
    Allow: .css

    URL-адреса

    Изменяйте URL-адреса, когда обновляете контент. Я уже упоминал History API, но вам следует знать, что в фреймворках JavaScript используется маршрутизатор, который позволяет производить сопоставление с чистыми URL-адресами. Не используйте октоторпы (символ #) для маршрутизации. В особенности это является проблемой в Vue и некоторых ранних версиях Angular. В таком URL-адресе как abc.com/#something, часть, следующая за символом #, обычно полностью игнорируется сервером. Чтобы исправить это в Vue, обратитесь к вашим разработчикам и измените следующий код.

    Маршрутизатор Vue:
    Используйте режим History вместо традиционного режима Hash.
    
    const router = new VueRouter ({
    mode: ‘history’,
    router: [] //массив ссылок для маршрутизации
    )}

    Дублированный контент

    В случае JavaScript на один и тот же контент могут вести несколько URL-адресов, что приводит к проблемам с дублированным контентом. Причиной может быть разный регистр, идентификаторы, параметры в идентификаторах и т. д. Все варианты ниже могут существовать.

    domain.com/Abc
    domain.com/abc
    domain.com/123
    domain.com/?id=123

    Решение простое. Выберите одну версию, которую вы хотите проиндексировать и установите канонические теги.

    SEO-плагины

    В фреймворках JavaScript их обычно называют модулями. Существуют версии для большинства популярных фреймворков таких как React, Vue и Angular. Найти их можно поиском по запросу “framework + название модуля”, например, “React Helmet”. Meta tags (Метатеги), Helmet и Head — примеры популярных модулей со схожей функциональностью, которые позволят вам установить многие популярные теги, необходимые для SEO.

    Страницы ошибок

    Поскольку фреймворки JavaScript не выполняются на стороне сервера, они не могут вызвать серверную ошибку, например, 404. У вас есть пару разных опций в случае страниц с ошибками:

    1. Используйте редирект JavaScript на страницу, которая отвечает статус-кодом 404
    2. На несрабатывающую страницу добавьте тег noindex и какое-нибудь сообщение об ошибке, например, “404 страница не найдена”. Она будет обрабатываться как мягкий 404, поскольку настоящий код статуса будет 200.

    Карта сайта

    В фреймворках JavaScript обычно есть маршрутизаторы для сопоставления с чистыми URL-адресами. В большинстве этих маршрутизаторов присутствует дополнительный модуль, который также может создавать карты сайта. Найти их можно поиском по запросу “ваша система + router sitemap”, например, “Vue router sitemap” (Vue маршрутизатор с картой сайта). Во многих решениях рендеринга также может быть возможность создания карты сайта. Поищите их в Google по запросу “система + sitemap”, например, “Gatsby sitemap” (Gatsby карта сайта), и вы точно найдете уже существующее решение.

    Редиректы.

    SEO-специалисты привычны к 301/302 редиректам, используемым на стороне сервера. А вот JavaScript обычно выполняется на стороне клиента. Это не проблема, поскольку Google обрабатывает страницы, получаемые редиректом. Редиректы все так же передают все сигналы такие как PageRank. Обычно эти редиректы можно найти в коде по “window.location.href”.

    Интернационализация

    Существует несколько вариантов модулей для различных фреймворков, которые поддерживают некоторые функции, необходимые для интернационализации, такие как hreflang. Обычно они переносятся на различные системы и включают локализацию и интернационализацию или все те же самые модули, используемые для тегов заголовков, наподобие Helmet, которые можно использовать для добавления нужных тегов.

    Отложенная загрузка

    Для обработки отложенной загрузки существуют модули. Если вы еще не заметили, при работе с фреймворками JavaScript существуют модули практически для всего, что вам нужно. Lazy и Suspence являются самыми популярными модулями для отложенной загрузки. Будет разумно отложить загрузку изображений, но не откладывайте загрузку контента. Это можно сделать с помощью JavaScript, но таким образом контент может некорректно собраться поисковыми системами.

    Заключение

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

    Остались вопросы? Дайте знать в Twitter.

    Trans­la­tion: Ole­sia Korob­kaSEO in Fajela.