CSS-in-JS преимущества использования и возможные проблемы, статический рендеринг

Содержание материала:

Влияние javascript на продвижение сайта

Привет, Друзья! В этой статье я расскажу какое оказывает влияние javascript на продвижение сайта. Итак, поехали!

Какое влияние оказывает javascript на продвижение сайта

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

Как работает Javascript

Вот краткое представление о JavaScript для тех, кто с ним совсем не знаком.

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

Рендеринг на стороне клиента и на стороне сервера

Есть две концепции, которые нужно упомянуть при разговоре о JavaScript. И очень важно понять различия между ними: рендеринг на стороне сервера и рендеринг на стороне клиента.

Традиционно, как и в случае со статическими HTML-страницами, код обрабатывается на сервере (рендеринг на стороне сервера). При посещении страницы Google-бот получает полный и «готовый» контент, поэтому ему не нужно ничего делать, кроме как загружать CSS-файлы и показывать информацию в вашем браузере.

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

Очевидно, что если бот Google не может обработать и правильно отобразить ваш JavaScript, он не сможет увидеть страницу и контент, который вы бы хотели ему показать. И именно здесь возникает большинство проблем с поисковой оптимизацией JavaScript и SEO-продвижением.

Теперь давайте посмотрим, как можно избежать этих проблем.

Как проверить, что сайт читается правильно

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

Вот несколько вариантов, которые могут вам помочь.

1. Команда site:

Прежде всего, команда site: покажет, сколько страниц вашего сайта в настоящее время индексируется Google. Если многие из них еще не указаны в индексе, это может быть признаком проблем с внутренними ссылками (перелинковкой).

Во-вторых, вы можете проверить, проиндексировал ли Google и Яндекс ваш JavaScript-контент.

Для этого нужно найти определенную строку в тексте, которая не представлена в исходном HTML-коде и загружается только после выполнения JavaScript. После этого найдите эту строку в индексе Google, используя команду site:yourdomain.com.

Обратите внимание, что это не работает с командой «cache:», поскольку кэшированные версии страниц содержат только оригинальный, еще не отрендеренный код.

2. Chrome 41

В августе 2020 года в Google обновили «Руководство поиска» и объявили, что используют Chrome 41 для рендеринга. Это коренным образом изменило SEO, ведь теперь стало возможным проверить, как Google фактически отображает страницу, а не гадать и надеяться на лучшее.

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

3. Chrome DevTools

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

Самый быстрый и простой способ проверить, загружаются ли все JavaScript-элементы без каких-либо действий пользователя, — использовать Chrome DevTools:

  1. Откройте ваш сайт в Chrome.
  2. Откройте таблицу элементов в DevTools.
  3. Посмотрите, как отображается ваша страница, просмотрев DOM фактической страницы, созданной браузером, убедитесь, что все важные навигационные и контент-элементы уже присутствуют там.

Я рекомендую проверить это и в Chrome 41. Это обеспечит уверенность в том, что робот Google технически способен увидеть все.

Конечно, вы также можете проверить это в своей текущей версии Chrome и провести некоторые сравнения.

4. Функция Fetch and Render в Google Search Console

Еще один полезный инструмент, который поможет представить, как Google отображает ваш веб-сайт, — функция Fetch and Render в Google Search Console.

Сначала вам нужно скопировать и вставить URL-адрес. Затем нажать Fetch and render и немного подождать. Это позволит вам увидеть, сможет ли робот Google обработать вашу страницу и увидеть связанные статьи, копии или ссылки.

Вы также можете использовать Mobile-Friendly Test от Google, который покажет вам ошибки JavaScript и код отображаемой страницы.

5. Анализ серверных логов

Последнее, к чему вы можете прибегнуть, чтобы проверить, как Google-бот обходит ваш сайт, — это анализ серверных логов. Если внимательно изучить логи, можно проверить, посещал ли робот Google определенные URL-адреса и какие разделы он просканировал или нет.

Существует множество аспектов, которые можно анализировать с помощью серверных логов. Например, вы можете проверить, посещает ли Googlebot ваши старые статьи: если нет, возможно, есть проблемы со ссылками, которые могут быть вызваны проблемами с JS.

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

Серверные логи не покажут, как бот Google видит страницы. Вы сможете проверить только то, были ли страницы просканированы и какие коды ответов были отправлены. Для определения того, были ли какие-то проблемы вызваны JavaScript, потребуется дополнительный анализ.

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

Возможные проблемы рендеринга сайта

Даже если ваша страница отображается правильно в разделе Fetch and Render в Search Console, это не означает, что вы можете выдохнуть и расслабиться. Есть и другие проблемы, за которыми нужно следить.

Начнем с одной из самых больших проблем, с которыми вам придется иметь дело…

1. Время ожидания

Хотя точное время ожидания не определено, говорят, что Google не может ждать скрипта дольше 5 секунд. Если скрипт загружается более 5 секунд, Google обычно не индексирует контент, который он создает.

Fetch and Render покажет, может ли Google прорендерить страницу, но эта функция ничего не скажет. Важно помнить, что Fetch and Render прощает гораздо больше, чем стандартный робот Google, поэтому вам нужно предпринимать дополнительные шаги, чтобы убедиться, что скрипты, которые вы используете, могут загрузиться менее чем за 5 секунд.

2. Ограничения браузера

Как мы упоминали ранее, Google использует несколько устаревшую версию своего браузера для рендеринга веб-сайтов: трехлетний Chrome 41. И так как технология JavaScript развилась и продолжает развиваться очень быстро, некоторые из ее новейших функций, которые работают в последние версии Chrome, не поддерживаются в Chrome 41.

Поэтому лучшим решением является загрузить браузер Chrome 41 (ту самую версию, которую Google использует для веб-рендеринга) и ознакомиться с ним. Проверьте лог консоли, чтобы увидеть, где возникают ошибки, чтобы ваши разработчики исправили их.

3. Контент, требующий пользовательского действия для загрузки

Мы уже говорили об этом, но это действительно стоит повторить: Google-бот не действует как пользователь. Он не нажимает на кнопки, не кликает «читать дальше», не открывает вкладки, не заполняет какие-либо формы… Он только читает и переходит.

Это значит, что весь контент, который вы хотите обработать, должен быть загружен в DOM сразу же, а не после того, как действие было выполнено.

Это особенно важно в отношении контента с кнопкой «читать дальше» и меню, например, вида «гамбургер».

Как помочь боту Google лучше рендерить сайт

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

Избегайте ссылок OnClick

Поисковые системы не считают onclick=»window.location=» обычными ссылками, а это значит, что в большинстве случаев они не будут ходить по такой навигации. И поисковики точно не будут относиться к ним как к сигналам о внутренней ссылке.

Исключительно важно, чтобы ссылки находились в DOM перед кликом. Вы можете проверить это, открыв «Инструменты разработчиков» в Chrome 41 и проверив, были ли уже загружены важные ссылки без каких-либо дополнительных действий пользователя.

Избегайте # в URL-адресах

Идентификатор фрагмента # не поддерживается и игнорируется роботами Google. Так что вместо использования URL-адреса вида example.com/#url, старайтесь работать с чистыми URL-адресами — example.com/url.

Уникальные URL-адреса для уникального контента

Каждая часть вашего контента должна «где-то» находиться, чтобы поисковая система смогла его проиндексировать. Вот почему важно помнить, что если вы динамически меняете контент без изменения URL-адреса, вы не позволяете поисковым системам получать к нему доступ.

Не допускайте ошибок JavaScript

HTML прощает многое, а вот JavaScript — нет.

Если на вашем сайте есть ошибки в скриптах JS, они просто не будут выполняться, что может привести к тому, что контент вообще не отображается. Одна ошибка в скрипте может создать эффект домино, вызвав множество дополнительных ошибок на всем сайте. И как я думаю все понимают, это вызовет серьезные проблемы в его раскрутке.

Чтобы проверить код и не допустить ошибок JavaScript, вы снова можете использовать Chrome DevTools и просмотреть вкладку «Консоль», чтобы узнать, какие ошибки возникли и в какой строке кода JavaScript.

Не блокируйте JavaScript в robots.txt

Блокирование JS-файлов — очень старый метод, но он применяется довольно часто. В некоторых CMS он иногда встречается по умолчанию. И хотя его целью является оптимизация бюджета обхода, блокировка JavaScript-файлов (и таблиц CSS) считается очень плохой практикой. Но не принимайте это на веру, вот что сам Google говорит по этой теме:

«Мы рекомендуем убедиться, что робот Google может получить доступ к любому встроенному ресурсу, который вносит значительный вклад в видимый контент вашего сайта или его макет …»

Поэтому не делайте ничего подобного:

Пререндер

Когда вы поймете, что у Google возникла проблема с рендерингом вашего сайта на JavaScript, вы можете использовать пререндер.

Пререндер предоставляет готовый HTML-«снимок» вашего сайта. Это означает, что бот Google получает не JavaScript, а чистый HTML. В то же время пользователь, который посещает сайт, получает ту же версию страницы, но насыщенную JavaScript.

Наиболее популярным решением является использование внешних сервисов для пререндера, таких как Prerender.io, который совместим со всеми наиболее важными структурами JS.

Использовать это решение очень просто — вам просто нужно добавить промежуточное программное обеспечение или сниппет на свой веб-сервер.

Заключение

Как видите влияние javascript на продвижение сайта очень велико, а тема поисковой оптимизации для JavaScript является самой динамичной темой в мире SEO и, безусловно, стоит вашего внимания, тем более, что она развивается так быстро. Проблемы, описанные в этой статье, являются лишь небольшой частью того, с чем вы можете работать, чтобы быть уверенным, что робот Google правильно читает ваш сайт.

Обучение продвижению сайтов

Для тех кто хочет научиться выводить сайты в ТОП 10 поисковых систем Яндекс и Google, я организовал онлайн-уроки по SEO-оптимизации (смотри видео ниже). Все свои интернет-проекты я вывел на посещаемость более 1000 человек в сутки и могу научить этому Вас. Кому интересно обращайтесь!

На этом сегодня всё, всем удачи и до новых встреч!

Анатолий

Вам также может понравиться

Задачи SEO специалиста

Модель оплаты интернет рекламы

Новые позиции продвигаемого мной сайта

Добавить комментарий Отменить ответ

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.

Vue.js и SEO: как оптимизировать реактивные сайты для поисковых систем и ботов

Индексируются ли сайты, созданные с помощью реактивных фреймворков, Google и другими поисковыми системами? Обязательно ли настраивать предварительный рендеринг, как советуют SEO-консультанты? Или они не правы?

Реактивные JavaScript – фреймворки (такие как React, Vue.js и Angular) в последнее время стали очень популярны, и неудивительно, что они используются во все большем количестве веб-сайтов и приложений благодаря их гибкости, модульности и простоте автоматизированного тестирования.

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

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

Немного предыстории проблемы

Как работает индексация

Чтобы ваш веб-сайт был проиндексирован Google, его должен сканировать Googlebot (программное обеспечение для автоматической индексации, которое посещает ваш веб-сайт и сохраняет содержимое страниц в его индексе) по ссылкам на каждой странице. Робот Googlebot также ищет специальные XML-файлы Sitemap на веб-сайте для поиска страниц, которые могут быть неправильно связаны с вашим сайтом, и для получения дополнительной информации (например о том, как часто меняются страницы на веб-сайте и когда они в последний раз менялись).

Немного истории

Еще несколько лет назад (до 2009 года) Google индексировал только HTML-код веб-сайта. Общеизвестным SEO правилом было то, что важные ссылки и контент не должны быть созданы с помощью JavaScript, поскольку они не будут проиндексированы Google, и это так же может повлечь за собой штрафы для веб-сайта, потому что Google может посчитать это «поддельным контентом», как если бы владелец сайта пытался показать пользователям что-то отличное от того, что было показано поисковым системам.

Мошенники часто помещали много HTML-контента, оптимизированного для SEO, а прятали его от реальных пользователей с помощью JavaScript. Google всегда предостерегал от этой практики:

«Предоставление роботу Google другого контента, который отображается пользователю, считается маскировкой и противоречит нашим правилам для веб-мастеров (Webmaster Guidelines)».

Вы можете быть оштрафованы за это. В некоторых случаях вас могут оштрафовать за предоставление разного контента разным пользовательским агентам на стороне сервера, а также за переключение контента через JavaScript после загрузки страницы. Я думаю, что это показывает нам, что Google в действительности распознавал контент созданный JavaScript – по крайней мере, для сравнения окончательного HTML сайта (после выполнения JavaScript) и необработанного HTML, который он анализировал для своих индексов. Но Googlebot не выполнял JavaScript все время, и Google не использовал сгенерированный JavaScript контент для целей индексации.

Затем, учитывая возросшее использование AJAX для отображения динамического контента на веб-сайтах, Google предложила «схему сканирования AJAX» (AJAX crawling scheme), чтобы помочь пользователям индексировать веб-сайты на основе AJAX. Но это было очень сложно в реализации; по сути, веб-сайт требовал рендеринга страниц с включенным содержанием AJAX. По запросу Google сервер должен был предоставит версию страницы со всем (или большей частью) контентом, который был бы сгенерирован динамически с помощью JavaScript, включенного в HTML-страницу – предварительно визуализированной как HTML-снимок контента. Этот процесс предоставления сервером контента, который предназначался для создания на стороне клиента, подразумевал, что тем, кто хочет создать сайт, который в значительной степени полагается на JavaScript, и при этом индексировался в Google, приходилось проходить через множество технических проблем.

Например, если содержимое, прочитанное AJAX, поступило из внешней веб-службы, необходимо было дублировать те же вызовы веб-службы на стороне сервера и создать на стороне сервера тот же HTML, который был бы создан на стороне клиента. Это было очень сложно в реализации, потому что до появления Node.js требовалось, по крайней мере, частично дублировать одну и ту же логику рендеринга в двух разных языках программирования: JavaScript для фронтенд интерфейса и PHP, Java, Python, Ruby и т. д. для бэкэнд. Это называется «рендеринг на стороне сервера» (server-side rendering), и это может привести к очень сложно архитектуре: если вы внесли важные изменения в способ рендеринга контента на фронтенде, вам придется дублировать эти изменения на бэкэнде.

Единственная альтернатива, позволяющая избежать дублирования логики, заключалась в том, чтобы рендерить свой сайт с помощью браузера, выполняющего JavaScript, и сохранять конечные результаты на своем сервере а затем передовать их Googlebot. Это похоже на то, что сейчас называется «предварительный рендеринг» (pre-rendering).

Google (с его схемой сканирования AJAX) также гарантировал, что вы избежите штрафов из-за того, что в этом случае вы предоставляете разный контент роботу Googlebot и пользователю. Но с 2015 года Google не рекомендует использовать AJAX crawling scheme и на официального сайте в блоге (official blog post), написано:

«Сегодня, если вы не запрещаете работу Googlebot он будет сканировать JavaScript или CSS, и он способен распознавать веб-страницы, так же как современные браузеры».

Это говорит нам не о том, что Googlebot внезапно приобрел возможность выполнения JavaScript при индексации веб-страниц, поскольку мы знаем, что он делал это в течение очень долгого времени (по крайней мере, для проверки поддельного контента и мошенничества). Вместо этого нам сообщили, что результат выполнения JavaScript будет проиндексирован и использован в поисковой выдаче.

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

Как Google на самом деле индексирует страницы, созданные с помощью фреймворков?

Эксперимент

Чтобы увидеть, как Google на самом деле индексирует веб-сайты, созданных с помощью фреймворков, я провел небольшой эксперимент. Я создал небольшой сайт с Vue.js и по-разному отобразил разные части текста.

Содержание сайта взято из описания книги Infinite Jest Дэвида Фостера Уоллеса в Infinite Jest Wiki. Есть пара вводных текстов для всей книги и список персонажей с их индивидуальной биографией. Какой контент я разместил на сайте:

  • Разместил текст в статическом HTML за пределами основного контейнера Vue.js;
  • Разместил текст, который визуализируется немедленно после запуска Vue.js, так как он содержится в переменных, которые уже присутствуют в коде приложения: определил его в объекте data;
  • Разместил текст, который визуализируется Vue.js из объекта data, но с задержкой 300 мс;
  • Биографии персонажей я загрузил с помощью REST API, который я специально создал с помощью Sandbox. Поскольку я предполагал, что Google выполнит код веб-сайта и через некоторое время остановится, чтобы сделать снимок текущего состояния страницы, я настроил каждый url возрастающую задержку: первая с 0 мс, вторая с 300 мс, третий с 600 мс и так далее до 2700 мс.

Каждая биография персонажа была сокращена и содержала ссылку на подстраницу, которая доступна только через Vue.js (URL генерируются Vue.js с использованием API истории), но не на стороне сервера (если вызвать URL-адрес страницы на прямую, то будет ответ 404). Я это сделал, чтобы проверить, будут ли они тоже проиндексированы. Хотя я сразу предположил, что они не будут проиндексированы, поскольку они не являются правильными ссылками, которые отображаются на стороне сервера, и Google никак не сможет направить пользователей на эти ссылки напрямую. Просто я хотел проверить этот момент.

Я опубликовал этот небольшой тестовый сайт на своей странице Github и попросил Google его проиндексировать – взгляните.

Результат

Результаты эксперимента оказались следующими:

  • Содержимое, находящееся в статическом HTML-контенте, хорошо индексируется Google (что довольно очевидно);
  • Содержимое, генерируемое Vue в режиме реального времени, так же всегда индексируется Google;
  • Содержимое, которое генерируется Vue, но отображается через 300 мс, так же индексируется;
  • Содержимое получаемое через веб-сервис с некоторой задержкой иногда проиндексировалось а иногда нет. Я проверял индексацию страницы Google в разные моменты, и контент, который был вставлен последним (через пару секунд), иногда индексируется, а иногда нет. Контент, который отображается довольно быстро, в большинстве случаев индексируется, даже если он поступает от асинхронного вызова внешней веб-службы. Это зависит от наличия у Google бюджета рендеринга для каждой страницы и сайта, который зависит от его внутренних алгоритмов, и может сильно отличаться в зависимости от рейтинга вашего сайта и текущего состояния очереди рендеринга Googlebot. Таким образом, вы не можете полагаться на контент, поступающий от внешних веб-сервисов, для индексации;
  • Подстраницы (так как они не доступны в виде прямой ссылки) не индексируются.

Что этот эксперимент говорит нам? По сути, Google индексирует динамически генерируемый контент, даже если он поступает из внешнего веб-сервиса, но не гарантируется, что контент будет проиндексирован, если он «поступит слишком поздно». У меня был подобный опыт с другими реальными, производственными веб-сайтами помимо этого эксперимента.

Конкурентный SEO

Итак, контент индексируется, но что этот эксперимент не говорит нам: будет ли контент ранжироваться на конкурентной основе? Будет ли Google предпочитать сайт со статическим содержанием динамически генерируемому сайту? Это не простой вопрос.

Исходя из моего опыта, я могу сказать, что динамически генерируемый контент может занимать верхние позиции в поисковой выдаче. Я работал над сайтом для новой модели крупной автомобильной компании, запустил новый сайт с новым доменом третьего уровня. Сайт был полностью создан с помощью Vue.js – с очень небольшим содержанием в статическом HTML, кроме тегов и meta описаний.

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

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

Мы вынуждены были опубликовать сайт без предварительной визуализации (pre-rendering) из-за сжатых сроков и нехватки времени, отведенного на проект.

Анимированный текст

То, что Google точно не индексирует, это сильно анимированный текст. Сайт одной из компаний, с которой я работаю, Rabbit Hole Consulting, содержит множество текстовых анимаций, которые выполняются, пока пользователь выполняет прокрутку.

Основные тексты на главной странице сайта не предназначены для индексации поисковыми системами, поскольку они не оптимизированы для SEO. Они не используют ключевые слова: они предназначены только для сопровождения пользователя в концептуальном путешествии по компании. Текст вставляется динамически, когда пользователь входит в различные разделы сайта.

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

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

Предварительный рендеринг (pre-rendering)?

Итак, почему столько суеты по поводу предварительного рендеринга – будь то на стороне сервера или во время компиляции проекта? Это действительно необходимо? Хотя некоторые фреймворки, такие как Nuxt, значительно упрощают его создание, это все равно нелегкое дело, поэтому выбор, использовать его или нет, не является простым.

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

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

Другие соображения

Совместимость

До недавнего времени Googlebot использовал довольно старую версию Chromium (проект с открытым исходным кодом, на котором основан Google Chrome), а именно версию 41. Это означало, что некоторые недавние функции JavaScript или CSS не могли корректно отображаться Google (например, IntersectionObserver, Синтаксис ES6 и т.д.).

Google недавно объявил, что теперь он запускает последнюю версию Chromium (74, на момент написания) в Googlebot, и что эта версия будет регулярно обновляться. Тот факт, что Google использовал Chromium 41, могло иметь большое значение для сайтов, которые решили не учитывать совместимость с IE11 и другими старыми браузерами.

Ошибки Javascript

Если вы полагаетесь на то, что Googlebot выполняет ваш JavaScript для визуализации жизненно важного контента, то следует избегать серьезных ошибок JavaScript, которые могут помешать отображению контента. Хотя боты могут анализировать и индексировать HTML, который не совсем корректен (хотя всегда желательно иметь действительный HTML на любом сайте!), если есть ошибка JavaScript, препятствующая загрузке некоторого контента, Google не сможет проиндексировать этот контент.

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

Лучше иметь какое-то программное обеспечение для проверки ошибок в реальном времени (например, Sentry или LogRocket), которое будет предупреждать вас о любых ошибках, которые вы можете и не обнаружить во время модульного или ручного тестирования.

Другие поисковые движки

Другие поисковые системы не работают так же хорошо, как Google с динамическим контентом. Похоже, что Bing вообще не индексирует динамический контент, как и DuckDuckGo или Baidu. Вероятно, этим поисковым системам не хватает ресурсов и вычислительных мощностей, которыми обладает Google.

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

Другие боты

Помните, что на ваш сайт будут заходить и другие боты. Наиболее важными примерами являются Twitter, Facebook и другие боты социальных сетей, которым необходимо получать метаинформацию о ваших страницах, чтобы показать предварительный просмотр вашей страницы, когда она связана с их пользователями. Эти боты не будут индексировать динамическое содержимое, а будут отображать только метаинформацию, найденную в статическом HTML.

Подстраницы

Если ваш сайт представляет собой так называемый «одностраничный веб-сайт», и весь соответствующий контент расположен на одной странице HTML, у вас не возникнет проблем с индексированием этого контента в Google. Однако если вам нужно, чтобы Google проиндексировал и отобразил какую-либо дополнительную страницу на веб-сайте, вам все равно нужно будет создать статический HTML-код для каждого из них – даже если вы используете JavaScript фрейворк для проверки текущего URL-адреса и предоставления соответствующего содержимого для размещения на этой странице. В этом случае мой совет – создавать серверные (или статические) страницы.

Заключение

При исследовании этой статьи я пришел к следующим выводам:

Зачем использовать server-s >

Никак не могу взять в толк в чем смысл рендеринга на стороне сервера.
Мой взгляд на ситуацию (чисто мои умозаключения, так как аргументированной информации зачем, нигде не встретил, натыкаюсь только на мануалы — «пошаговая инструкция»):
плюсы:
— отдаем клиенту готовый (рендеренный) контент, (но вроде как на клиенте сейчас довольно мощное железо, а там где слабое, реакт всё равно не пойдет в силу устаревшего ПО)
— приложение отдается по фрагментам (вроде как взаимодействие происходит быстрей, за счет скорости получения данных)
минусы:
— расход лишних ресурсов сервера (насколько я понял, для каждого клиента происходит компиляция нужного компонента из исходников)
— большой тайм-аут отклика (мне так кажется, если хороший трафик большое количество параллельных процессов рендера. Или я про рендеринг не так понимаю?)
— отсутствует возможность кеширования данных на клиенте (ведь при каждом запросе новый рендер компонента)
— лишние требования к коду во время разработки (классическое redux хранилище вроде как уже не катит, нужно следить, чтобы данные не пропали при переходе по страницам.

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

  • Вопрос задан более двух лет назад
  • 17498 просмотров

приложение отдается по фрагментам

Нет, это не задача серверного рендеринга

расход лишних ресурсов сервера

Обычные же сайты так и отдаются — через серверный шаблонизатор, и никто не умер. Тут получается то же самое, только язык JS и шаблонизатор React.

отсутствует возможность кеширования данных на клиенте

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

лишние требования к коду во время разработки

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

То есть сохранять состояние приложения, у меня например redux, на сервере для каждого клиента?

приложение отдается по фрагментам

Нет, это не задача серверного рендеринга

Топ-пост этого месяца:  Как сделать сайт для слабовидящих joomla

То есть сохранять состояние приложения, у меня например redux, на сервере для каждого клиента?

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

Хм, есть приложение, на несколько страниц (роутов). Смотрел sources, js файлы при переходе по роутам меняются (решил, что вебпак генерит по запросу новые файлы).

Использовать SSR, если.
Тебе нужно с Bing, Yahoo или Baidu,Google.
У вас уже есть работающее приложение, требующее максимальной производительности, и оно готово заплатить за дополнительные ресурсы сервера.

Не используйте SSR, если.

Ресурсы сервера ограничены, возможно, из-за низкого бюджета или невозможности масштабирования.

SSR это очень круто но в некоторых случаях это имеет недостатки.

  1. Рендеринг стороне сервера помогает seo, но иногда Google может найти ваше содержание без SSR.
  2. SSR обычно повышает производительность вашего приложения, но не всегда.
  3. Это повысит сложность приложении, что означает меньше времени работы с другими функциями и улучшениями.

SSR улучшает производительность

После того как браузер загрузит HTML-и CSS, он может отображать визуализированные компоненты пользователю, не дожидаясь загрузки JavaScript или реакции на визуализацию.

Если файл JavaScript очень велик, это может быть большим улучшением.

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

SSR снижает производительность

SSR является больше работы для вашего сервера, так что ваш ответ HTTP займет немного больше времени, чтобы вернуться. Гораздо дольше, если ваши серверы находятся под большой нагрузкой.

Размер вашего HTML будет увеличена и займет больше времени для загрузки. Для большинства приложений этого должно быть незначительным, но может стать фактором, если ваш REACT компоненты содержат длинные списки или таблицы.

Другие факторы производительности

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

Мы не можем сказать, производительность лучше с SSR или производительность хуже с SSR. В целом ни заявление будет верно сказать что ssr это хорошо

Про оптимизацию рендеринга — с оптимизмом

Статья была впервые опубликована здесь.

У меня есть мечта, и она утопична: я хочу, чтобы мои работали идеально. JQuery, AngularJs, React, Vue.js — все обещают производительность. Но проблема совсем не во фреймворках и не в JavaScript. Проблема в том, как браузер рендерит страницу. А делает он это очень плохо.

Если бы браузер отлично справлялся с рендерингом, то не появился бы такой инструмент, как React Native. Под капотом React Native всё тот же JavaScript, а View нативное, и разница в производительности между нативным приложением и приложением на React Native не будет заметна для рядового пользователя. Другими словами, проблема не в JavaScript.

Если оптимизировать, то как раз рендеринг. Инструментов, которые нам даёт JavaScript и API браузера, недостаточно. Два года я пытаюсь сделать работу своих продуктов плавной и быстрой, но тщетно. Я почти смирился с тем, что веб останется таким навсегда. В этой статье я собрал всё, что успел узнать об оптимизации рендеринга и применить на проектах, над которыми работал, и рассказываю о своих надеждах на ближайшее будущее. Это будущее, в котором я хочу опираться на устойчивый фундамент стандартов и API браузера, а не и репозитории для оптимизации производительности.

Гибридные приложения и производительность

Я писал приложения с довольно тривиальной функциональностью: новостные ленты с комментариями, категориями и тегами. В них можно смотреть видео, делать поиск по новостям Ну, ещё . Ничего сложного. По причине NDA я не могу показать вам эти проекты, зато в блоге нашей компании мы рассказываем о принципах выбора подхода к мобильной разработке.

В разработке гибридных приложений хорошо. JavaScript меня полностью устраивал, полностью устраивали меня и элементы интерфейса, которые щедро предоставляли фреймворки Framework7 и Ionic. Даже плагинов, позволяющих пользоваться нативными функциями, хватало. Пиши одно приложение и получай сразу десять — под все платформы, какие только придумали. Мечта да и только. Но сейчас будет «но», жирное и ставящее крест на всём.

Как только приложение становится заметно сложнее, чем «Hello, world!», начинаются проблемы с производительностью. Приложение работает лучше, чем мобильная версия сайта, но далеко не так хорошо, как аналогичное нативное приложение.

Если и готов с этим мириться, то для меня это стало вызовом. Мне нужно было написать гибридное приложение так, чтобы его невозможно было отличить от нативного. Тогда я покопался и пришёл к одному простому выводу: с js всё хорошо, проблема в рендеринге. Я перепробовал всё от transform: translate3d(0,0,0) (который вскоре перестал работать) и до замены градиентов png с . Это, конечно же, не решало проблему, а лишь чуть маскировало её. По ссылкам несколько таких хаков:

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

Medium, у вас проблемы

На сайтах и в приложениях мы видим бесконечные ленты: Instagram, Facebook, Twitter, Medium — из этих примеров, пожалуй, можно составить свою ленту с подгрузкой. И в этом нет ничего плохого. Скролл позволяет перемещаться в пределах одного поста и перемещаться между постами. Можно скроллить быстро, можно медленно. Добавляешь новые элементы в список сколько душе угодно. Я и сам так делал.

Давайте проведем эксперимент. У вас шумный кулер? Откройте Medium.com и мотайте вниз. Как скоро ваш кулер выйдет на максимальные обороты? Мой результат — примерно 45 секунд. И это не Chrome виноват. И даже не то, что моему ноутбуку много лет. Проблема в том, что никто не занимается оптимизацией того, что мы видим во viewport.

Что же происходит, когда мы мотаем ленту? Оказавшись внизу страницы, мы получаем от сервера ещё немного постов, и они добавляются в конец списка. Список растёт бесконечно. Что делает браузер? Ничего. Посты в начале ленты всё ещё существуют и браузер всё еще рендерит их. И visibility: hidden тут никак не поможет, даже если мы будем вешать это свойство на каждый пост, который находится за пределами viewport . Кстати, такая бесполезная оптимизация была замечена мною в Ionic. Серьезно. Но потом это исправили. Если кому интересно, вот тема на форуме Ionic, которую я создал, чтобы обсудить проблему.

Загадочный мир оптимизации

Что же мешает писать хороший, оптимизированный код? Мешает то, что мы не так много знаем об этом процессе. Большая часть знаний пришла к нам методом проб и ошибок, а статьи с заголовком вроде «Как браузер рендерит страницу» рассказывают нам о том, как HTML совмещается с CSS и как страница разбивается на слои. Мне непонятно, что происходит, когда я добавляю в DOM новый элемент или добавляю элементу новый класс. Какие элементы при этом пройдут пересчёт и рендеринг?

Вот мы добавим новый элемент в список. Что дальше?

  1. Новый элемент нужно отрендерить и поставить на место;
  2. нужно заново сдвинуть другие элементы списка;
  3. нужно заново рендерить другие элементы списка;
  4. нужно обновить высоту «родителя»;
  5. обновился «родитель», и теперь непонятно, поменялись ли соседние элементы.

И так далее до корня DOM. В итоге мы рендерим всю страницу целиком.

Рендеринг в браузере работает иначе. Вот одна из массы статей на эту тему, где автор рассказывает о процессе совмещения и и о том, как браузер впоследствии рисует полученную конструкцию. Всё очень здорово, однако не совсем ясно, что может сделать разработчик, чтобы помочь браузеру. Есть неофициальный ресурс CSS Triggers, на котором представлена таблица, позволяющая определить, какие вызывают Layout/Paint/ в браузере, но так как страницы обычно содержат большое количество стилей и элементов, единственный разумный выход — это постараться исключить всё, что может ударить по производительности.

В общих чертах оптимизация сводится к решению следующих задач:

  • облегчить CSS, сделать стили удобочитаемыми для браузера;
  • избавится от тяжелых для рендеринга стилей (теней и прозрачности лучше избегать вовсе);
  • уменьшить число DOM элементов и производить как можно меньше изменений в нём;
  • Правильно работать с GPU.

Всё это немного помогает оптимизации загрузки страницы, но что делать если хочется большего?

Отсечение лишнего

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

Многие знают про Virtual list/Virtual scroll/Grid View/Table View. Названия разные, но суть одна: это компонент для эффективного отображения очень длинных списков на странице. В основном подобные интерфейсные компоненты используют в мобильной разработке.

GitHub полон Virtual list, Virtual grid Оптимизация вполне рабочая, это факт. В списке из 10 тысяч элементов можно создать контейнер длинной в 10 000 px, умноженных на высоту одного элемента, далее следить за скроллом и рендерить только видимые пользователю элементы плюс ещё . Сами элементы позиционируются при помощи «translate: transformY( * px)». Я недавно изучал Vue.js 2.0 и написал такой компонент за пару часов.

Есть несколько вариантов реализации, и разница между ними лишь в том, как мы позиционируем элементы и разбиваем ли их на группы, но это не столь важно. Проблема в том, что событие scroll при идеальных условиях срабатывает ровно столько раз, сколько пикселей было проскроллено. То есть очень много. Добавьте к этому необходимость производить вычисления при каждом срабатывании события. На мобильных устройствах событие scroll и сама механика scroll работает . Вывод из этого следует довольно простой: scroll event плохо подходит для таких задач.

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

IntersectionObserver

Вот теперь на сцену выходит IntersectionObserver, первый луч надежды, упавший на описанное мной во вступлении будущее. Фича новая, поэтому вот информация о поддержке браузерами на сайте caniuse.com. А вот немного материалов по ней:

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

Теперь немного практики. Мне захотелось сделать виртуальный скролл с подгрузкой элементов, используя IntersectionObserver. Задача примерно такая:

  • бесконечная лента с постами, в которых есть заголовок, картинка и текст;
  • содержание постов и их высота не известны заранее;
  • никаких остановок на подгрузку контента;
  • 60 fps.

А вот что я понял, пока писал этот компонент:

  • нужно переиспользовать элементы, производя минимум операций с DOM;
  • не нужно создавать IntersectionObserver для каждого элемента списка, достаточно двух.

Принцип работы

Контент разбивается на части по 12 постов каждая. Когда компонент инициализировался, в DOM находится только одна такая часть. Первая и последняя часть имеют скрытый элемент вверху и внизу соответственно. За видимостью этих элементов мы следим. Когда из этих элементов попадает на экран, мы добавляем новую часть и удаляем уже ненужную. Таким образом мы имеем в DOM две части по 12 постов одновременно.

Чем это удобнее отслеживания скролла? Если высота постов неизвестна, приходится искать элемент в DOM и узнавать её. Это не очень удобно и не очень производительно.

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

Меньше слов больше дела: вот демо. И я прошу обратить внимание на то, что цель здесь — увидеть работу IntersectionObserver на реальном примере.

Вот тут можно посмотреть на FPS, если скроллить со скоростью беглого просмотра ленты (изображение кликабельно):

И максимально быстро (изображение кликабельно):

FPS очень редко падает ниже 60, но всего на пару кадров и не ниже 45. Хороший результат, учитывая то, что браузер не знает размер картинок и текста заранее.

Заключение

Это не самый впечатляющий и полезный пример использования IntersectionObserver. Куда интереснее попробовать использовать его в связке с компонентами React/Vue/Polimer. Тогда можно при инициализации компонента вешать на него IntersectionObserver и продолжать инициализацию только когда он появится во viewport. Это открывает широкие возможности. Остаётся лишь скрестить пальцы и верить, что IntersectionObserver получит своё дальнейшее развитие.

Анализ и оптимизация React-приложений

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

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

Введение

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

Попытаемся ответить на эти вопросы, взглянув на самый простой способ создания React-приложений — на использование средства create-react-app (CRA). У нового проекта, созданного с помощью этого инструмента, имеются следующие зависимости:

  • Основная библиотека react , которая позволяет работать с компонентами React: 2.5 Кб.
  • Библиотека react-dom , позволяющая выводить компоненты на страницу, превращая их в структуры, подходящие для вставки в дерево DOM: 30.7 Кб.
  • Небольшой объём кода, в который входит и шаблон первого компонента: около 3 Кб.

Эти данные получены для React 16.6.3.

Для того чтобы узнать о том, сколько времени займёт загрузка нового CRA-приложения на телефоне Moto G4, можно воспользоваться сервисом WebPageTest.

Время загрузки сайта на телефоне Moto G4 с использованием разных сетей

Это приложение, разновидность «Hello, World», размещено на хостинге Firebase, исследуется его загрузка в браузере Chrome с использованием трёх типов соединений:

  • 4G (9 Мбит/с)
  • 3G (1.6 Мбит/с)
  • Медленное 3G-соединение (400 Кбит/с)

Тут нужно учитывать и сетевые задержки.

Почему я, для эксперимента, использовал Moto G4? Это — простой недорогой телефон, похожий на те телефоны, которыми, в виде основных устройств, пользуются многие люди в развивающихся странах. В 4G-сети приложение загрузилось за 2 секунды. В медленной 3G-сети для того, чтобы страница вышла в интерактивный режим работы, понадобилось более 4 секунд.

Хотя эти показатели и довольно интересны, они не особенно полезны в том случае, если вы не знаете о том, кем являются ваши пользователи. То, что вы определяете как «медленно», может полностью отличаться от того, что «медленным» считаю я или кто-то ещё. И ваше восприятие «быстрой» загрузки сайта может быть искажено тем, каким устройством и каким сетевым соединением вы пользуетесь. Если включить в этот эксперимент настольный компьютер, подключённый к интернету по проводному соединению, можно увидеть, как велико может быть различие между «быстрой» и «медленной» загрузкой сайта.

Время загрузки сайта на настольном компьютере и на Moto G4

Для того чтобы повысить производительность React-приложений, при построении которых используется библиотека React, что называется, «из коробки», намечены улучшения React DOM, которые нацелены на упрощение некоторых вещей. Так, система событий содержит множество полифиллов, которые, для многих новых браузеров, не нужны, и команда разработчиков рассматривает варианты их удаления или упрощения в тех случаях, если это возможно. Понаблюдать за этим можно здесь.

Можно ли измерить текущий уровень производительности веб-сайтов?

Типичное React-приложение может содержать множество компонентов и библиотек сторонних разработчиков. Это означает, что производительность «Hello, World»-приложения не даёт нам особенно ценных сведений о том, как загружаются настоящие приложения. Есть ли способ узнать о том, насколько высокопроизводительным является большинство сайтов, построенных с использованием некоей технологии (вроде React)?

Ответить на этот вопрос нам, возможно, может помочь ресурс HTTP Archive. Это — опенсорсная платформа, которая ориентирована на наблюдение за тем, как построен веб. Делается это путём ежемесячного обхода миллионов сайтов, анализа их с помощью WebPageTest и записи сведений о них. В эти сведения входит число запросов, метрики, касающиеся загрузки данных, размеры передаваемых данных и другие показатели.

Вот ещё один интересный инструмент — расширение для Chrome, которое называется Library-Detector-for-Chrome. Оно позволяет выяснять то, какие JavaScript-библиотеки используются на странице. Оно было недавно включено, в качестве инструмента аудита страниц, в Lighthouse. Это говорит о том, что информация, которую даёт это расширение, может быть получена для множества сайтов, сведения о которых хранятся в HTTP Archive. Это может помочь тем, кто хочет проанализировать результаты испытания тысяч сайтов, на которых используется конкретная JavaScript-библиотека (механизм определения React находится здесь).

Полный набор данных HTTP Archive общедоступен, найти его можно на BigQuery. После исследования 140000 сайтов, использующих React, на предмет их загрузки в искусственно смоделированной мобильной среде (набор данных 2020_01_01 ), удалось выяснить следующее:

  • Медиана показателя First Meaningful Paint (первое значимое отображение, время отрисовки важных элементов) составила 6.9 с.
  • Медиана показателя Time to Interactive (время до интерактивности, время загрузки элементов взаимодействия) составила 19.7 с.

Вы можете исследовать эти данные и самостоятельно.

Почти 20 секунд нужно на то, чтобы пользователь смог бы начать взаимодействовать с сайтом. И это, в общем-то, происходит, так сказать, здесь и сейчас, хотя и может выглядеть неправдоподобно. Такое можно видеть на крупных сайтах при работе с ними со слабых устройств на медленных линиях связи. Кроме того, сейчас мне хотелось бы озвучить несколько причин, по которым эти данные стоит рассматривать с долей скептицизма.

  • На производительность сайтов влияет множество факторов. Среди них — объём JavaScript-кода, отправляемого пользователю, число изображений и других материалов, выводимых на странице, и так далее. Некорректно будет сравнивать производительность любых сайтов, основанных на React, с производительностью страницы с надписью «Hello, World» в том случае, если во внимание не принимаются другие факторы.
  • Если попытаться получить данные, заменив в запросе React на название какой-нибудь другой библиотеки, будут получены очень похожие цифры.

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

Рост объёмов JavaScript-кода

Общая проблема современных веб-сайтов, не привязанная к конкретной библиотеке, связана с объёмом JavaScript-кода, которое обычно приходится загружать клиенту при просмотре страниц. На ресурсе HTTP Archive уже имеется хороший отчёт об этом. Если в двух словах, то вот как выглядят медианные значения объёмов JavaScript, загружаемых с веб-сайтов в разные годы:

  • 74.7 Кб — мобильные веб-страницы, 15 декабря 2011 года.
  • 384.4 Кб — мобильные веб-страницы, 15 декабря 2020 года.

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

  • 381.5 Кб — мобильные веб-страницы, 15 декабря 2020 года (вот запрос).

Всё это позволяет сделать вывод о том, что в наши дни создаются веб-сайты, которые включают в себя больше JS-кода, чем сайты, которые создавались несколько лет назад. Это — важное наблюдение. Сайты стали больше, они стали более интерактивными и более сложными, и объём JS-кода этих сайтов постепенно, с каждым годом, растёт. Вероятно, вы уже об этом слышали, но чем больше JavaScript-кода вы отправляете в браузер — тем больше времени нужно на то, чтобы его распарсить, скомпилировать и выполнить. Это, в результате, замедляет сайт.

Важно отметить, что каждый сайт уникален, равно как и пользовательская база каждого сайта. Многие разработчики, сайты которых включают в себя более 300 Кб JS-кода, не сталкиваются с тем, что большинство их пользователей страдает от проблем с производительностью, и это совершенно нормально. Однако если вы беспокоитесь о том, что с просмотром вашего React-сайта у ваших пользователей могут возникать сложности, для того, чтобы оценить реальное положение дел, лучше всего начать с профилирования.

Профилирование и анализ страниц

Профилирование и анализ React-приложений может рассматриваться с двух точек зрения:

  • Во-первых, речь идёт об оценке производительности компонентов. Это влияет на то, как пользователи взаимодействуют с сайтом. Например, если при щелчке по кнопке выводится список, это должно выполняться быстро, но, в том случае, если в ходе выполнения этой операции выполняется повторный рендеринг сотен компонентов, при том, что в нём нет необходимости, эта операция будет восприниматься как медленная.
  • Во-вторых, речь идёт о том, как скоро приложение приводится в рабочее состояние. То есть о том, через сколько времени после начала загрузки сайта пользователь сможет с ним взаимодействовать. Объём кода, отправляемый пользователю в ходе загрузки первой страницы сайта — это пример фактора, влияющего на то, как быстро пользователь сможет начать работу с приложением.

Оценка производительности и оптимизация компонентов

Попытаемся выразить в одном предложении смысл алгоритма реконсиляции React, или суть того, что называют «виртуальной DOM». Это будет выглядеть так: «React предпринимает действия для нахождения различий между новым деревом DOM и старым деревом для того, чтобы понять, что именно в пользовательском интерфейсе должно быть обновлено при изменении данных в компоненте». Это создаёт гораздо меньшую нагрузку на систему, чем повторный рендеринг всего приложения при каждом изменении состояния или свойств (тут можно почитать о разнице между O(n 3 ) и O(n)). Вот статья Дэна Абрамова , где можно найти пояснения по поводу реконсиляции.

Даже учитывая то, что эти оптимизации встроены во внутренние механизмы React, всегда можно столкнуться с проблемой, когда компоненты в приложении рендерятся повторно тогда, когда происходить это не должно. В маленьких приложениях это может быть незаметным, но это может серьёзно повлиять на производительность приложений, на страницы которых выводятся сотни компонентов.

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

  • Панель Performance инструментов разработчика Chrome.
  • Профилировщик инструментов разработчика React.

▍Анализ производительностью с использованием панели Performance инструментов разработчика Chrome

React использует API User Timing для того чтобы измерять время, приходящееся на каждый шаг жизненного цикла компонента. Сведения о производительности React-приложений можно собирать и анализировать с помощью инструментов разработчика Chrome. Это позволяет понять то, насколько эффективно компоненты подключаются, выводятся на страницу и отключаются в ходе взаимодействия пользователя со страницей или при её перезагрузках.

Анализ производительности компонентов

Вот хороший материал на эту тему, посвящённый исследованию производительности приложений, написанных с использованием React 16, с применением инструментов разработчика Chrome.

API User Timing используется лишь в ходе разработки. Оно, в продакшне, отключается. В таких условиях могут использоваться более быстрые реализации подобных механизмов, не оказывающие серьёзного влияния на производительность. Именно необходимость в таких механизмах и стала одной из причин разработки более нового API Profiler.

▍Анализ производительности с помощью профилировщика из инструментов разработчика React

С выходом библиотеки react-dom 16.5 в инструментах разработчика React можно пользоваться новой панелью, называемой Profiler. Она позволяет анализировать производительность рендеринга компонентов. Делается это с помощью API Profiler, средствами которого собирается информация о времени выполнения операций для всех компонентов, подвергаемых повторному рендерингу.

Панель Profiler представляет собой самостоятельную вкладку в инструментах разработчика React. Тут, как и в случае с панелью Performance инструментов разработчика Chrome, можно записывать сведения о действиях пользователя и о перезагрузках страниц для того, чтобы собрать данные для анализа производительности компонентов.

Сбор данных с помощью инструментов разработчика React

После окончания сбора данных будет выведен так называемый «пламенный график», показывающий время, необходимое для рендеринга компонентов на странице.

Пламенный график профилировщика

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

Просмотр сведений о коммитах в профилировщике

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

  • Один — для индикатора загрузки, который выводится в ходе загрузки списка элементов.
  • Ещё один представляет момент, когда вызов к API завершён и список выводится в DOM.

На рисунке, в его правой части, показаны полезные метаданные, включающие в себя сведения о коммите или данные компонента, такие, как свойства и состояние.

Работая с профилировщиком React, можно просматривать и другие данные, представленные различными графиками. Подробности о профилировщике React можно почитать в этой публикации из блога React.

Для того чтобы немного усложнить наш пример, рассмотрим похожую ситуацию, но теперь будем выполнять множество обращений к API для загрузки трендовых репозиториев по разным языкам программирования (вроде Golang, JavaScript, и так далее). Как можно ожидать, при таком подходе в нашем распоряжении оказывается больше коммитов.

Увеличение числа коммитов при усложнении схемы работы с приложением

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

▍Минимизация ненужных операций повторного рендеринга компонентов

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

    Можно воспользоваться методом жизненного цикла компонента shouldComponentUpdate():

Можно, для конструирования компонентов, основанных на классах, использовать PureComponent:

Для функциональных компонентов можно использовать memo:

  • Можно произвести мемоизацию селекторов Redux (например, с помощь reselect).
  • Можно оптимизировать вывод очень длинных списков, применив виртуализацию (например — с помощью react-window).
  • Вот и вот — пара полезных видео, где рассматривается применение профилировщика React для поиска узких мест в приложениях.

    Оценка производительности и оптимизация приложений

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

    Протестировать веб-страницу с помощью Lighthouse можно тремя способами:

    • Используя интерфейс командной строки Node.js.
    • Используя расширение Chrome.
    • С помощью панели Audits инструментов разработчика Chrome.

    Вот как выглядит Lighthouse на панели Audits.

    Lighthouse на панели Audits

    Lighthouse обычно не требуется много времени на сбор всех необходимых ему данных со страницы и на выполнение множества проверок этих данных. После того, как эти операции завершены, Lighthouse выводит отчёт с итоговой информацией.

    Для того чтобы понять, что загрузка страницы в браузер предусматривает и загрузку слишком большого объёма JavaScript-кода, и сделать вывод о том, что объём этого кода стоит уменьшить, нужно обратить внимание на следующие фразы из отчёта:

    • Eliminate render-blocking resources
    • JavaScript boot-up time is too high
    • Avoid enormous network payloads

    Если Lighthouse сообщает об этих проблемах из-за того, что страница использует JS-бандл слишком большого размера, самым первым, что стоит рассмотреть в качестве способа исправления проблемы, является разделение бандла. Дело в том, что если код можно разбить на фрагменты, некоторые из которых нужны только для работы с определёнными страницами сайта, то у нас нет причин этой возможностью не воспользоваться.

    ▍Разделение JS-бандлов

    Один из способов разделения кода на части является использование динамического импорта:

    Синтаксис импорта может выглядеть как вызов функции, но он позволяет импортировать любой модуль асинхронно, с использованием механизма промисов. В данном примере сначала импортируется метод sortby из библиотеки lodash , а затем выполняется метод doSomethingCool() .

    Приложение для сортировки чисел

    В этом примере происходит следующее:

    1. Пользователь щёлкает по кнопке для того, чтобы отсортировать три числа.
    2. Импортируется lodash.sortby .
    3. Вызывается метод doSomethingCool() , который сортирует числа и выводит их в новом узле DOM.

    Это — предельно простой, искусственный пример, так как если кому-то понадобится сортировать числа на веб-странице, то он, вероятно, просто воспользуется методом Array.prototype.sort() . Но хочется надеяться, что этот пример помог мне показать то, почему использование динамического импорта при выполнении пользователем неких действий может оказаться полезным.

    Синтаксис динамического импорта является сравнительно новым, он в настоящее время находится на третьей стадии процесса принятия новых возможностей JavaScript комитетом TC39. Этот синтаксис уже поддерживается в Chrome и в Safari, а также бандлерами Webpack, Rollup и Parcel.
    Если говорить о React, то тут существуют абстракции, созданные для упрощения процесса разбиения кода на уровне компонентов с использованием технологии динамического импорта. Один из примеров реализации этого механизма — React.lazy :

    Одной из основных проблем, связанных с асинхронной загрузкой различных частей приложения, является работа с задержками в работе приложения, с которыми может столкнуться пользователь. Для этого существует компонент Suspense , который может быть использован для того, чтобы «приостановить» вывод на экран дерева некоего компонента. При использовании его вместе с React.lazy , можно, если код нужного компонента всё ещё загружается, показать пользователю индикатор загрузки:

    Компонент Suspense пока ещё не работает при применении серверного рендеринга. Если вы хотите воспользоваться методиками разделения кода в React-приложениях, которые рендерятся на сервере, используйте, следуя совету, данному в документации React, библиотеку наподобие loadable-components .

    LoadingComponent может быть использован с loadable-component во время загрузки основного компонента как индикатор.

    Обратите внимание на то, что для того, чтобы использовать библиотеку loadable-components в серверном рендеринге, нужно кое-что настроить.

    Подумаем над тем, где именно в приложении стоит пользоваться техниками разделения кода. Пожалуй, легче всего разделять код, основываясь на маршрутах. В документации React есть пояснения о том, как это может выглядеть с использованием маршрутизатора React и Suspense .

    ▍Стоит ли заниматься разделением кода, которое опирается на прокрутку страницы?

    Вот ещё одна интересная библиотека для разделения кода, react-loadable-visibility, которая построена на базе библиотеки loadable-components и веб-API Intersection Observer. Её можно использовать для загрузки компонентов по мере того, как они становятся видимыми при прокрутке страницы.

    ▍О кэшировании того, что стоит кэшировать

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

    Ускорение загрузки страниц с использованием кэширования

    Workbox — это набор библиотек, который упрощает включение в проект сервис-воркеров, избавляя программиста от необходимости писать весь необходимый код с нуля. С использованием CRA 2.0 для того, чтобы воспользоваться этим механизмом, достаточно удалить всего пару символов из файла src/index.js . Это даст вам возможность задействовать стандартный сервис-воркер с базовыми возможностями по кэшированию.

    Подробности о сервис-воркерах и о библиотеке Workbox вы можете найти в этом материале.

    ▍Серверный рендеринг и потоковая передача данных

    В основе технологий серверного рендеринга веб-сайтов лежит идея снижения нагрузки на устройства пользователей за счёт отправки в браузеры готового HTML-кода, сгенерированного на сервере, точно такого же, который получился бы в браузере в результате работы механизмов программного формирования страницы. Это позволяет сделать так, чтобы пользователи видели бы содержимое страниц гораздо быстрее, чем в том случае, когда им, чтобы сформировать страницу, сначала нужно загрузить некий JS-код, а потом дождаться окончания его выполнения.

    Для того чтобы обеспечить правильную работу этого механизма, разработчик сайта должен быть уверен в том, что браузер использует DOM-структуры, сгенерированные на сервере, вместо того, чтобы самостоятельно пересоздавать разметку (например, с использованием метода hydrate() в React). Это может выглядеть так, будто страница загружается быстрее, но это может увеличить время, необходимое для того, чтобы пользователь мог бы взаимодействовать со страницей.

    Топ-пост этого месяца:  Всплывающий блок рядом с заданным блоком

    Работая с React 16, можно воспользоваться возможностями потоковой передачи данных при серверном рендеринге компонентов. Вместо того чтобы пользоваться методом renderToString() для формирования HTML-строки, можно использовать метод renderToNodeStream() для возврата Readable-потока Node.

    Потоковая передача данных с сервера позволяет клиенту получать и по очереди выводить разные части HTML-документа вместо того, чтобы выводить сразу весь документ. Хотя серверный рендеринг всегда улучшает показатель, связанный с первым выводом страницы приложения на экран, этот подход способен ещё сильнее улучшить данный показатель.

    Если вы применяете React для разработки статических сайтов, то, вместо вышеупомянутого метода, используйте метод renderToStaticNodeStream.

    ▍Использование предварительного рендеринга в тех случаях, когда серверный рендеринг неприменим

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

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

    Если вы хотите использовать эту технологию в своём приложении, вам могут в этом помочь библиотеки наподобие react-snap, которые пользуются возможностями Puppeteer.

    Вот хороший материал, посвящённый различным подходам к серверному рендерингу.

    ▍Об извлечении важных стилей, описанных в виде CSS-in-JS

    Многие React-разработчики, по разным причинам, используют CSS-in-JS-библиотеки вроде emotion и styled-components. Среди таких причин можно отметить возможность использования стилей, область действия которых ограничена компонентом, автоматическое создание селекторов, основанных на свойствах, передаваемых компонентам, и другие. Если при использовании технологии CSS-in-JS не проявлять должную осмотрительность, можно столкнуться с проблемой, которая заключается в том, что все стили будут вычисляться во время выполнения кода. Это означает, что стили будут применяться только после того, как JavaScript-бандл страницы будет выполнен, что приводит к тому, что пользователь может некоторое время наблюдать нестилизованное содержимое страницы. Как и в случае с любыми другими проблемами, касающимися производительности, эта проблема усиливается в тех случаях, когда для работы с сайтом используются слабые мобильные устройства или медленные сетевые соединения.

    Ситуация, в которой пользователь некоторое время видит нестилизованное содержимое страницы (взято отсюда)

    Если в вашем приложении уже используется какая-нибудь разновидность серверного рендеринга, исправить проблему со стилями можно путём извлечения самых важных из них. Библиотеки emotion и styled-components поддерживают эту возможность. Стили можно извлечь в Readable-поток Node. У Glamor есть отдельная библиотека, которая позволяет делать то же самое.

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

    Тут показано Preact-приложение, но этот пример позволяет оценить возможности по извлечению стилей (источник)

    Если всё, что вам нужно от технологии CSS-in-JS — это использование стилей, область действия которых ограничена компонентами, и вы при этом не хотите перегружать приложение библиотеками, реализующими более широкий функционал, возможно, вам подойдёт библиотека astroturf. Используя её, вы получите не все возможности, доступные в типичной библиотеке такого рода, но в вашем распоряжении будет возможность работать с управляемыми стилями компонентов, использование которых не создаст дополнительной нагрузки на систему во время выполнения кода приложения.

    ▍Доступность сайтов

    Если некое приложение называется «прогрессивным», это значит, что его создатели постарались чтобы у всех пользователей была бы возможность получить доступ хотя бы к некоторой его части. Если с вашим сайтом не могут работать люди с ограниченными возможностями, это значит, что прогрессивным он называться не может.

    Для того чтобы выявить проблемы с доступностью некоей страницы, отлично подойдёт Lighthouse. Для нахождения проблем, характерных для React-элементов, можно воспользоваться проектом React A11y.

    Кроме того, вы можете рассмотреть возможность использования react-axe для проведения аудита готового, отрендеренного приложения, а не только его JSX-кода.

    ▍Улучшение возможностей по добавлению сайтов на домашний экран

    Хорошо ли ваш сайт работает на мобильных устройствах? Есть ли у вас сервис-воркеры, которые кэшируют некоторые материалы, что позволяет приложению работать и без подключения к интернету? Является ли ваше приложение настолько полезным, что пользователям может захотеться разместить значок для быстрого доступа к нему на домашнем экране их устройств?

    Если вы отвечаете на все эти вопросы положительно, тогда вам нужно написать для своего сайта манифест веб-приложения. Это повысит удобство пользователей по работе с приложением при его «установке» на их мобильные устройства. Манифест позволяет много всего настраивать, в том числе — значок приложения, фоновый цвет и цвет темы.

    При использовании create-react-app создаваемый этим инструментом шаблон приложения оснащается стандартным файлом-манифестом:

    Разное

    Вот некоторые идеи, которые направлены на оптимизацию труда программистов. Их применение, кроме того, ведёт к снижению объёма кода приложений. Чем меньше объём кода приложения — тем лучше. Почему это так? Дело в том, что чем компактнее будет код приложения, тем меньше данных придётся передавать с сервера в браузер и тем быстрее будут загружаться страницы приложения.

    ▍Atomic CSS

    Методика использования атомарных CSS-стилей (Atomic CSS) предусматривает создание классов, решающих чрезвычайно узкие задачи и отличающихся маленькими размерами. Например, при таком подходе отдельный класс используется для того, чтобы назначить кнопке синий фон:

    Отдельный класс используется для настройки свойства кнопки padding :

    И так далее. Хотя это приводит к необходимости добавлять очень большое количество значений в атрибут class большинства узлов DOM, это даёт преимущество, заключающееся в том, что разработчику приходится писать гораздо меньше CSS-кода, чем обычно. Достигается это за счёт использования библиотек, ответственных за автоматическую настройку селекторов. Одной из таких библиотек является Tachyons.

    Ограничение области действия стилей границами компонента с использованием атомарных классов стало привычной практикой для многих разработчиков. А библиотеки вроде tachyon-components даже позволяют применять эти стили с использованием API, похожего на API styled-components :

    Хотя это может и не быть основной причиной, по которой разработчики используют библиотеки для работы с атомарными стилями, устранение необходимости в создании новых CSS-селекторов благодаря использованию фиксированного набора «одноразовых» классов означает, что объём CSS-кода, отправляемого в браузер, всегда будет оставаться неизменным.

    Хуки позволяют делать с функциональными компонентами много всего такого, что раньше было доступно только при работе с компонентами, основанными на классах. Работа с состоянием компонента — это лишь один из примеров:

    Хуки можно использовать для решения следующих задач:

    • Включение в компонент состояния без использования компонентов, основанных на классах (useState).
    • Включение в компонент побочных эффектов без использования компонентов, основанных на классах (useEffect).
    • Повторное использование одной и той же логики в разных компонентах благодаря созданию собственных хуков.

    Всё это позволяет включать в компоненты логику, которая может быть использована повторно в других местах приложения. До появления хуков для того, чтобы пользоваться некоторыми из этих возможностей, применялась библиотека recompose.

    Вот запись с мероприятия React Conf, в начале которой можно найти подробное разъяснение концепции хуков.

    Хотя замечательные возможности хуков и сами по себе приведут к их широкому распространению, можно отметить, что их использование способно помочь и в деле уменьшения размеров пакетов JavaScript-кода приложений. Как пишет Дэн Абрамов , если говорить об увеличении библиотеки React после добавления в неё поддержки хуков, то оно составило примерно 1.5 Кб (минифицированная и сжатая версия). Весьма вероятно то, что применение хуков поможет уменьшить размер бандлов из-за того, что код, в котором используются хуки, лучше, чем код, в котором используются компоненты, основанные на классах, поддаётся минификации.

    Итоги

    Здесь мы рассмотрели множество вопросов, касающихся оптимизации производительности React-приложений. Вот краткая сводка по тем шагам, которые может предпринять тот, кто стремится сделать свои приложения быстрее:

      Измерьте производительность компонентов приложения, воспользовавшись одним из следующих инструментов:

    • Панель Performance инструментов разработчика Chrome.
    • Профилировщик инструментов разработчика React.
  • Минимизируйте число ненужных операций повторного рендеринга компонентов

    • Там, где это применимо, воспользуйтесь методом жизненного цикла компонента shouldComponentUpdate() .
    • Для компонентов, основанных на классах, используйте PureComponent .
    • Для функциональных компонентов используйте React.memo .
    • Воспользуйтесь технологией мемоизации селекторов Redux (например, с помощью reselect ).
    • Примените технологии виртуализации при выводе очень длинных списков (например, с помощью react-window ).
  • Измерьте общую производительность приложения с помощью Lighthouse.
  • Улучшите общую производительность приложения, применив следующие подходы к оптимизации:

    • Если вы не пользуетесь серверным рендерингом — подумайте о разбиении кода компонентов с помощью React.lazy .
    • Если вы пользуетесь серверным рендерингом — разделяйте код компонентов с использованием библиотеки наподобие loadable-components .
    • Используйте сервис-воркеры для кэширования материалов, которые стоит кэшировать. Вам в этом может серьёзно помочь Workbox .
    • Если вы пользуетесь серверным рендерингом — используйте потоки вместо строк (с помощью renderToNodeStream и renderToStaticNodeStream ).
    • Серверный рендеринг вам не подходит? Тогда задействуйте предварительный рендеринг с использованием библиотек наподобие react-snap .
    • Извлекайте самые важные стили при использовании библиотек, нацеленных на реализацию технологии CSS-in-JS.
    • Постарайтесь сделать так, чтобы ваши приложения были бы доступны как можно более широкому кругу пользователей. Рассмотрите возможность использования библиотек React A11y и react-axe .
    • Оснастите свой проект манифестом веб-приложения в том случае, если полагаете, что мобильным пользователям будет удобно работать с ним, вызывая его с домашнего экрана их устройств.
  • Когда опенсорсный проект, наподобие React, приобретает огромнейшую популярность, вполне естественно ожидать от него следующего:

    • Улучшение его API, идущее через создание средств, упрощающих создание приложений.
    • Появление библиотек сторонних разработчиков, которые, опять же, упрощают создание приложений.

    Фраза «упрощение создания приложений» может означать очень много всего. Сюда относится и облегчение разработки веб-проектов, которые быстро загружаются на устройства пользователей и быстро работают.

    Уважаемые читатели! Как вы оптимизируете свои React-приложения?

    CSS-in-JS: преимущества использования и возможные проблемы, статический рендеринг

    Примечание: перевод заметки Rendering: repaint, reflow/relayout, restyle от Stoyan Stefanov. Освещается очень много прикладных аспектов отрисовки страниц в браузерах и построения дерева потока документа. Примечания далее курсивом. Термин reflow далее переводится как «перерасчет дерева отрисовка», чтобы отделить его от термина repaint (фактическая перерисовка страницы).

    Итак, что происходит в браузере, когда он отрисовывает HTML-страницу на экране? Как он обрабатывает выданную ему кашу из HTML-, CSS- и (возможно) JavaScript-кусков?

    Процесс отрисовки

    Разные браузеры проделывают это по-разному, но следующая диаграмма дает понимание об процессе в целом и более-менее подходит для всех браузеров, как только они загрузили весь код страницы.

    • Браузер анализирует HTML-код страницы (кашу из тегов) и строит некоторое DOM-дерево — представление данных, в котором каждому HTML-тегу соответствует свой узел, а текстовые куски между тегами соответствуют своим текстовым узлам. Корневым узлом такого дерева является documentElement (тег ). Затраты на время построения DOM-дерева исследовались в этихстатьях.
    • Браузер анализирует CSS-код, пытается понять все заложенным в нем хаки и корректно распознать все известные ему приемы, среди которых могут быть -moz , -webkit и другие расширения, которые он может не понимать и должен игнорировать. Информация по стилям строится каскадным образом: сначала идут правила по умолчанию из самого браузера (более подробно их размер исследовался в этой статье), затем идут пользовательские стили, затем авторские (автора страницы) — внешние, импортированные, внутренние, а уже потом — все стили, прописанные в атрибутах style HTML-тегов.
    • После этого наступает самая интересная часть: браузер строит дерево отрисовки. Дерево отрисовки в какой-то мере связано с DOM-деревом, но не соответствует ему полностью. Дерево отрисовки знает о текущих стилях (поэтому если вы спрячете div при помощи display: none , то он в это дерево не попадет, это не совсем верно, как видно из следующей статьи, но принцип тот). То же самое для других невидимых элементов: например, для тега head и всех вложенных элементов. С другой стороны в этом дереве DOM-узлы могут быть представлены в виде нескольких узлов, например, если каждая строка

    требует своего узла для отрисовки. Узел в таком дереве называется кадр (frame) или блок (box) (так же как и CSS-блок, соответствующий блочной модели). У каждого из этих блоков есть блочные CSS-свойства: ширина, высота, граница, поля, и т.д (таким образом, даже строчные (inline) элементы будут представлены в дереве отрисовки отдельными блоками).

  • После того как готово дерево отрисовки, его можно наконец и отрисовать(paint, draw) на экране.
  • За деревьями не видно леса

    Давайте рассмотрим следующий пример.

    Исходный HTML-код:

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

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

    Корневой элемент дерева отрисовки является кадром (блоком), содержащим все остальные элементы. Можно считать его внутренней частью окна браузера, так как он ограничивает область, в которой страница может располагаться. Говоря технически языком, в WebKit корневым узлом называется RenderView , и он соответствует первоначальному контейнеру по спецификации CSS, и является прямоугольной областью видимости, распространяющейся от начала страницы( 0 , 0 ) до ( window.innerWidth , window.innerHeight ).

    Давайте дальше посмотрим, как именно отображение элементов на экране вызывает рекурсивный просмотр дерева перерисовки. Здесь и далее термин (re)flow перевдится как перерасчет дерева перерисовки.

    Перерисовка и перерасчет дерева отрисовки

    На странице всегда присутствует хотя бы один расчет потока документа вместе с его отрисовкой (если конечно вы не фанат пустой страницы в браузере :)). После этого изменение входной информации, которая была использована для рендеринга страницы, может привести к одному (или обоим) пунктам ниже.

    1. Потребуется пересчитать некоторые части дерева перерисовки (или даже все дерево). Этот процесс называется перерасчет дерева отрисовки (reflow) или перерасчет макета документа (re-layout). Заметьте, что всегда есть хотя 1 такой перерасчет: при первичном отображении страницы.
    2. Некоторые части экрана нужно обновить, либо потому что изменились геометрические свойства узлов, либо какие-либо их стили (например, цвет фона). Этот процесс называется перерисовка (repaint, redraw).

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

    Что вызывает перерасчет или перерисовку

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

    • Добавление, удаление или обновление DOM-узлов.
    • Скрытие DOM-узла при помощи display: none (перерасчет или перерисовка) или visibility: hidden (только перерисовка, геометрия не меняется).
    • Движение, анимация DOM-элемента на странице.
    • Добавление файла стилей, изменение стилевых свойств элементов.
    • Пользовательские действия, например, изменения размера окна, изменение размера шрифта или (только не это) прокрутка страницы.

    Давайте рассмотрим пару примеров:

    Некоторые перерасчеты дерева отрисовки могут быть более «тяжелыми». Стоит рассматривать эти операции в терминах дерева отрисовки: если изменения касаются только узла, который является прямым потомком тела документа ( body ), то вполне вероятно, что другие узлы не будут затронуты. Но что произойдет, если вы начнете анимировать и увеличить блок вверху страницы, что будет смещать всю остальную страницу вниз? Видимо, это будет весьма затратно.

    Браузеры умнее

    Поскольку перасчеты потока документы и перерисовки, связанные с изменением дерева отрисовки, являются весьма непростыми операциями, браузеры пытаются всеми силами нивелировать негативные эффекты. Один подход заключается в отказе производить часть работы. По крайней мере, не в данный момент. Браузер может создать некоторую очередь, в которую будет вносить изменения, производимые скриптами, и выполнять эти изменения пачками. В этом случае несколько изменений, каждое из которых повлечет перерасчет, могут быть объединены в одно, и будет произведен только один перерасчет. Браузеры также могут сбрасывать состояние очереди (отрисовывать) страницу по истечению некоторого времени (100-200мс) или достижения некоторого количества (10-20) таких изменений.

    Но иногда скрипты могут предотвратить такое оптимизирующее поведение браузеров и заставить применить все накопившиеся в очереди изменения прямо сию секунду. Это происходит, когда вы запрашиваете следующую информацию о стилях:

    1. offsetTop , offsetLeft , offsetWidth , offsetHeight ,
    2. scrollTop /Left/Width/Height,
    3. clientTop /Left/Width/Height,
    4. getComputedStyle() или currentStyle в IE.

    Все вышеприведенные варианты запрашивают информацию о стиле DOM-узла у браузера. Этот запрос заставляет браузер выполнить все отложенные операции, чтобы выдать актуальную информацию. Все это приводит к выполнению перерасчета (и видимо, перерисовки).

    Например, плохой идеей будет устанавливать стили, запрашивая при этом информацию о них в одном и том же месте (например, внутри цикла):

    Уменьшение перерасчетов и перерисовок

    Для уменьшении негативных эффектов от перерасчета / перерисовки (относительно пользовательского восприятия) стоит, прежде всего, свести к минимуму любые обращения к стилевой информации, чтобы браузер мог максимально оптимизировать перерасчет дерева отрисовки. Что для этого нужно?

      Не изменяйте индивидуальные стилевые свойства одно за другим. Для масштабируемости кода и увеличения скорости реакции интерфейса нужно менять имена классов, а не сами стили. Но это предполагает статические классы. Если же стили полностью динамические (например, «всплытие» элементов), то необходимо редактировать свойство cssText вместо того, чтобы вносить изменения в свойство style самого элемента.

    Инструменты

    Примерно год назад не было ничего, что обеспечивало бы информацией о перерасчете и перерисовке страницы в браузере (это может быть и не так: я подозреваю, что в MS были свои внутренние средства для разработчиков, но о них никто не знал, ибо они были похоронены в глубине MSDN :P). Теперь ситуация изменилась, и очень сильно.

    Во-первых, появилось событие MozAfterPaint в ночных сборках Firefox, поэтому стали возможны такие плагины, как, например, этот (от Kyle Scholz), который использует это событие. mozAfterPaint — это очень прикольно, но оно сообщает только момент перерисовки (а не перерасчета дерева отрисовки, что является боле затратным).

    Далее. DynaTrace Ajax и более поздний SpeedTracer от Google (заметьте: оба трейсят (trace) :)) являются отличными инструментами для отслеживания перерасчетов и перерисовок, первый предназначен для IE, второй — для WebKit.

    Однажды в прошлом году Douglas Crockford заметил, что мы, возможно, делаем в CSS очень глупые вещи, но сами о них не знаем. И теперь есть, что возразить на это. Я немного участвовал в проекте на той стадии, что мы разбирались со следующей проблемой: незначительное увеличение пользователем шрифта (in IE6) загружало CPU на 100% в течение 10-15 минут, прежде чем страница снова появлялась на экране.

    Отлично, инструменты у нас есть, поэтому для нас уже не может быть поблажек в плане идиотского поведения в CSS.

    Ну, за исключением, может быть, одного: было бы, наверное, круто, если бы существовал инструмент, который бы показывал дерево отрисовки в дополнение к DOM-дереву?

    Практические примеры

    Давайте немного подробнее взглянем на указанные инструменты и продемонстрируем с их помощью разницу между изменением стилей (restyle, изменения в дереве отрисовки не касаются геометрии), перерасчетом (reflow, который изменяет макет документа) и перерисовкой (repaint).

    Давайте сравним два способа сделать одно и то же. Сначала мы будем менять некоторые стили (не затрагивающие макет) и после каждого изменения будем запрашивать стилевое свойство, никак с изменением не связанное.

    А затем то же самое, только все информационные запросы будут осуществляться после всех изменений в стилях:

    В обоих случаях вот определения используемых переменных:

    Теперь пусть эти два примера изменения стилей будут выполняться по клику на документ. Тестовая страница находится здесь: restyle.html (кликаем «dude»). Давайте назовем ее тестом изменения стилей (restyle test).

    Во втором тесте будет почти то же самое, только мы будем также менять и информацию о макете:

    Этот случай давайте назовем тестом изменения макета (relayout test), исходник здесь.

    Вот что выдает DynaTrace для первого теста (стили).

    Изначально у нас страница загрузилась, затем я кликаю один раз, чтобы выполнить первый сценарий (запрос стилей каждый раз, примерно в 2с). Затем кликаю еще раз, чтобы выполнить второй сценарий (запросы к стилям после всех изменений, примерно в 4с)

    Этот инструмент показывает, в какой момент закончилась загрузка страницы (это обозначает логотип IE). Затем курсор мыши находится на области, отвечающей за обработку клика. Увеличиваем масштаб (круто!), и вот более детальная картина:

    Тут уже очень хорошо видно, сколько времени ушло на JavaScript (синяя полоска) и сколько — на отрисовку (зеленая полоска). Это у нас еще простой пример, а как отличаются полоски по длине? Наколько дороже для браузера обходится отрисовка, чем исполнение JavaScript? Обычно в Ajax- и Rich-приложениях JavaScript не является узким местом, тормозит доступ к DOM-элементам и часть, отвечающая за отрисовку страницы.

    Отлично, теперь запускаем второй тест — на изменение макета, — который меняет геометрию. В этот раз проверяем «PurePaths». Это временная шкала + более детальная информация о каждом элементе на этой шкале. Я подсветил первый клик, где JavaScript вызвал отложенные операции по изменению макета.

    Снова увеличиваем масштаб и видим, что дополнительно к полоске «отрисовка» у нас появилась еще одна — «перерасчет дерева отрисовки», потому что в этом тесте мы его сознательно создаем в дополнение к перерисовке.

    Теперь давайте протестируем ту же самую страницу в Chrome и посмотрим на результаты SpeedTracer.

    Это первый тест по изменению стилей с увеличенным масштабом и обзором происходящего.

    Если кратко, то после клика происходит отрисовка. Но в случае первого клика 50% времени уходит на перерасчет стилей. Почему? Потому что мы запрашиваем информацию о стилях (даже не связанную с самими изменяемыми стилями) после каждого изменения.

    Увеличиваем события и видим в деталях, что происходит на самом деле: после первого клика стили пересчитываются 3 раза. После второго — только один раз.

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

    Но в случае детального просмотра мы видим, что первый клик вызвал три перерасчета дерева отрисовки (поскольку запрашивал информацию о вычисленных стилях), а второй — только один.

    Незначительное отличие между этими инструментами заключается в том, что SpeedTracer не показывает тот момент, когда задача по изменению макета запланирована и добавлена в очередь, а DynaTrace показывает. И поэтому DynaTrace не отображает разницу между изменением стилей и изменением макета, как SpeedTracer. Может быть, просто сам IE не делает между ними разницы? Также DynaTrace не показал три перерасчета дерева отрисовки в первом случае второго теста (когда мы запрашиваем информацию о стилях после каждого изменения макета). Может быть, это так IE работает?

    Ниже приведены дополнительные данные касательно этих двух тестов после запуска их достаточное количества раз.

    • В Chrome отказ от запроса вычисленных стилей при их изменении примерно в 2,5 раза быстрее (тест на изменение стилей) и 4,42 раза быстрее, если вы меняете и стили и макет (тест на изменение макеты).
    • В Firefox — в 1,87 и 1,64 раза быстрее, соответственно.

    По всем браузерам изменение стилей примерно в два раза быстрее, чем изменение стилей и макета страницы. За исключением IE6, где разницы составляет 4 раза.

    Заключение

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

    • Дерево отрисовки — визуальная часть DOM-дерева.
    • Узлы в дереве отрисовки называют кадры или блоки.
    • Изменение дерева отрисовки называется перерасчетом (reflow) в Mozilla и макетом (layout) во всех остальных браузерах, по-видимому.
    • Обновление на экране результатов перерасчета дерева отрисовки называется перерисовкой (repaint, redraw) (в IE/DynaTrace).
    • В SpeedTracer вводится понятие «перерасчета стилей» (стили, не изменяющие геометрию) против «макета».

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

    Самый простой способ ускорить загрузку сайта

    Скорость загрузки сайта влияет на позиции в поисковой выдаче.

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

    Далее рассмотрим что делать и принцип действия.

    Как ускорить загрузку сайта быстро и просто?

    На большинстве сайтов используется код JavasScript. По умолчанию робот использует последовательную загрузку скриптов.

    На практике наиболее распространенные сценарии применения скриптов следующие:

    • Подключение систем аналитики, таких как Google Analytics и/или Yandex Метрика;
    • Использование скриптов JavaScript при решении задач по user interface или user experience.

    Поисковая система оценивает скорость загрузки сайта через имитацию браузера пользователя.

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

    Критическим путем рендеринга (Critical Rendering Path) называется последовательность шагов, необходимых для первого отображения страницы.

    Если нет желания разбираться в технических деталях (все-таки уже потеплело на улице), то для ускорения загрузки страниц сайта просто прочитайте и внедрите следующие правила:

    • Код JavaScript должен быть вынесен во внешний файл;
    • К тегу script должен быть добавлен атрибут defer.

    Далее рассмотрим технические детали, полезные для понимания того, за счет чего происходит улучшение производительности сайта.

    До вывода страницы на экран проходит 6 этапов критического пути рендеринга:

    1. Построение DOM-дерева;
    2. Построение CSSOM-дерева;
    3. Запуск JavaScript;
    4. Создание Render-дерева;
    5. Генерация расположения;
    6. Визуализация.

    Под термином DOM (Document Object Model) подразумевается объектная модель страницы.

    Структура DOM выстраивается из узлов, так называемых нодов (от nodes).

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

    Под термином CSSOM (CSS Object Model) подразумевается объектная модель стилей страницы сайта.

    Не имеет значения то, как стили были заданы: объявлены явно или наследуются.

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

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

    Render-дерево представляет собой объединение из DOM и CSSOM, и включает только видимые элементы. Например, исключаются элементы, которые были скрыты с использованием display none.

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

    Поисковая оптимизация критического пути рендеринга

    Модели DOM и CSSOM связаны с JavaScript.

    JavaScript является блокирующим ресурсом для роботов, то есть JavaScript блокирует разбор HTML-документа.

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

    Но блокировки робота можно избежать!

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

    Есть 2 важных директивы:

    • async;
    • defer.

    При не использовании директив код выглядит так:

    BDD 2020: SPA+SEO. Как ПС индексируют и ранжируют JavaScript-rich сайты

    9-11 августа в Калининграде прошла шестая ежегодная конференция по интернет-маркетингу и заработку в сети Baltic Digital Days 2020. В первый день конференции Владимир Короленко (Kite – Digital Agency) выступил с мастер-классом на тему «JS+SEO: как ПС индексируют и ранжируют JavaScript-rich сайты».

    В один прекрасный день звонит маркетолог или владелец проекта и сообщает чудесную новость: «Ребята, мы тут посовещались с разработкой и решили переехать на SPA-сайт на JS-движке ReactJS. Подготовите нам рекомендации?».

    Ваши первые мысли, после осознания масштаба проблемы (в зависимости от того, сталкивались вы с JS-сайтами или нет):

    • «Блин, ну вот все же нормально было, зачем?»
    • «WTF??»/«Это еще что такое?»

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

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

    Что такое JS-сайты, SPA, React и т.д.

    Что же это за зверь такой «SPA-сайты» и чем они отличаются от статических сайтов на HTML, динамических на PHP и т.д.

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

    JavaScript изначально создавался для того, чтобы сделать web-страницы «живыми». Программы на этом языке называются скриптами. В браузере они подключаются напрямую к HTML и, как только загружается страничка, тут же выполняются.

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

    Single Page Application в переводе на русский язык означает «одностраничное приложение». Это web-приложение, работающее на языке JavaScript, компоненты которого (JavaScript-файлы, модули, CSS-файлы и т.д.) загружаются единожды на одной странице, а контент подгружается по необходимости.

    JS-фреймворки и библиотеки — это инструменты для построения динамических веб/мобильных/настольных приложений на языке JavaScript.

    В чем отличие от статических сайтов

    Главное отличие динамических сайтов на JavaScript от статических в том, что для поисковых систем это до сих пор «магия», которая усложняет индексацию на всех этапах обработки контента.

    Типичный для SPA-сайта HTML-код

    Страница полностью строится на стороне браузера пользователя. Браузер выполняет JavaScript и создает контент на лету.

    Контент, который видит пользователь, меняется в зависимости от взаимодействия с SPA-сайтом, при этом весь процесс происходит без перезагрузки страниц и на одном URL.

    Так видит пользователь страничку на проекте mybook.ru:

    А так для пользователя выглядит официальный сайт JS-фреймворка React:

    И вдруг внезапно. Так видит поисковой бот Google ту же самую страничку:

    А так для поискового бота Яндекса выглядит официальный сайт JS-фреймворка React:

    Краулер ПС обработать такой контент не способен. Нарушается сразу несколько основополагающих принципов индексации.

    • Нет перезагрузки страниц — есть только один URL, на котором находится весь контент.
    • Контент, который видит пользователь, отсутствует в пригодном для сканирования виде.
    • Любая не выловленная JavaScript ошибка может обернуться некорректной работой краулера на сайте и, как итог, выпадение из индекса.
    • Практически все ПС не способны обрабатывать JavaScript.

    На последнем пункте стоит остановиться подробнее.

    Что про JS говорят поисковые системы?

    Как думаете, что случится с проектом после переезда на SPA-движок, если ничего не предпринимать и оставить все как есть?

    Как разные JavaScript движки индексируются поисковиками? Основано на эксперименте, опубликованном на MOZ

    Google проиндексирует и обработает большую часть контента. Для обработки JavaScript используется механизм на основе браузера Google Chrome. Правда, со своими особенностями, о которых мы еще расскажем.

    Но в Рунете есть еще и Яндекс, который мы просто не можем игнорировать. Яндекс до сих пор обрабатывает динамический контент (JavaScript, AJAX) в порядке эксперимента. Для корректной индексации необходимо наличие полной HTML-копии страницы.

    Комментарии там же, ссылка на официальную рекомендацию Яндекса по индексации JS и AJAX

    Один из самых известных случаев произошел в начале июня — Яндекс перестал индексировать сайты, созданные на конструкторе Wix, после того как конструктор изменил алгоритм генерации страниц.

    По заявлению представителей Яндекса, теперь все хорошо и проблем с индексацией сайтов на Wix нет. Но факт остается фактом. Если вы не хотите проблем с индексацией на проекте — нужна статичная HTML-копия для Яндекса.

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

    Но прежде давайте разберемся, почему клиенты выбирают JS-фреймворки, несмотря на возможные проблемы.

    Почему клиенты выбирают JS-фреймворки

    Несмотря на то, что для многих крупных проектов переход на JS-движок — только дань моде, у JS-сайтов есть и настоящие плюсы.

    Сторона пользователя

    • Скорость. Отсутствие перезагрузки страниц обеспечивает быстрое взаимодействие с пользователем. От этого — максимально лояльная проекту аудитория и увеличение количества конверсий.
    • Отзывчивый (Responsive) дизайн вместо адаптива. Благодаря этому увеличивается количество устройств и потенциальных пользователей.
    • Расширенные возможности по персонализации контента. Зарегистрированному пользователю можно «собирать» максимально персонализированные страницы и разделы (умные ленты, рекомендации и т.д.).

    Сторона разработки

    • Модульность. Благодаря этой особенности JS-фреймворков становится возможно разделение продукта на компоненты, которые отдаются разным командам разработки. В итоге проект собирается как конструктор из кубиков. А сроки разработки сокращаются за счет параллельной работы.
    • Четкое разделение front-end и back-end команд разработки.
    • Широкие возможности по созданию архитектуры (можно собрать что угодно).
    • Проекты проще в разработке — код значительно короче благодаря возможности повторного использования компонентов.
    • Разные платформы (desktop и mobile приложения) на основе одного кода.

    Неочевидные плюсы SPA

    • Конкурентоспособность на рынке труда. Переход на новую и современную технологию, которая сейчас активно развивается — возможность привлечь лучших разработчиков. Крутые спецы не хотят работать с архаичными технологиями. А их присутствие в команде — часто само по себе толчок к развитию.
    • Рефакторинг. Если у вас две версии сайта (основной поддомен для десктоп-устройств и отдельный для мобильных), и над ними в разное время работали несколько команд разработки и верстальщиков, рано или поздно вы столкнетесь с необходимостью делать рефакторинг для развития проекта. В этом случае JS-фреймворки отличное решение. Вы сможете объединить все версии на одном коде, который значительно легче поддерживать и развивать дальше.

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

    Что же все-таки делать по SEO, если для проекта переход на SPA — единственный путь развития с точки зрения маркетинга и продукта?

    Варианты рендеринга, плюсы и минусы

    Есть очень важный технический термин, который в свете SPA-сайтов нужно запомнить и понять. Это понятие «рендеринг». Этот термин — ключ к успешному индексированию проекта.

    Рендеринг — это процесс перевода JS-кода в стандартный HTML-код, понятный для поисковиков.

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

    Часто на этапе выбора варианта рендеринга вас ждет диалог-баталия с клиентом и командой разработки. На этом этапе важно отстоять свою точку зрения — рассказать о том, как каждый вариант отразится на SEO проекта. Каждую ресурсоемкую задачу нужно хорошо обосновать (спойлер: она и правда ресурсоемкая). Скорее всего, разговор будет происходить так.

    WRS — технология обработки JS от Google

    Разработка: «Давайте не будем ничего делать? У нас хватает других задач. Просто переведем проект на JS, а поисковики уже сами во всем разберутся. Google — умеет индексировать JS, с помощью технологии WRS. Вот ссылка на официальный источник Google — разбирайтесь, раз не в курсе».

    WRS (web rendering service) — это технология рендеринга, основанная на обработке JS с помощью браузера Google Chrome (также ее называют CSR — client side rendering, т.е. рендеринг на стороне клиента).

    Когда можно использовать. Если совсем забыть про Яндекс (и другие ПС) и делать сайт для Google. В то же время из этой же ссылки следует, что технология основана на браузере Google Chrome M41. А это браузер 2015 года, поэтому множество новых возможностей будет проигнорировано и возможна некорректная обработка. Сравнить можно здесь.

    По официальным заявлениям умеет индексировать JS только Google. Про остальные ПС можно забыть или использовать более сложный и опасный метод — подмену по User-Agent.

    • Старый браузер Google Chrome 41 2015 года.
    • Google не действует как настоящий браузер (например, не переходит по ссылкам onclick).
    • Оптимизирует свои ресурсы на загрузку — не будет ждать дольше 5 секунд.
    • Anti-mobile First. Рендеринг на мобильных устройствах в любом случае займет кучу времени (в зависимости от характеристик аппарата). Например, чтобы обработать 1MB JS на мобильном устройстве Samsung Galaxy S7 нужно

    850ms, а на менее производительном Nexus 5 уже

    Статичная HTML-копия + AJAX Crawling Scheme

    Разработка: «Нам важен Яндекс. Давайте искать другое решение. Например, у Яндекса есть инструкция, в которой предлагается использовать для JS сайтов AJAX Crawling Scheme. Аналогичная инструкция есть и у Google».

    Суть метода — для каждой индексируемой динамической страницы должна быть статичная HTML-версия на отдельном Url+ ?_escaped_fragment_= в URL. Также нужно использовать метатег в коде динамической страницы, чтобы сообщить боту о наличии HTML-версии страницы.

    Т.е. чтобы проиндексировать http://site1.ru/example/, боту нужна страница http://site1.ru/example/?_escaped_fragment_= с идентичным содержимым.

    !На сегодня это официальная рекомендация от Яндекс по поводу JS и AJAX сайтов.

    • Это устаревшая технология, которая отмечена Google как «нежелательная» с 2015 года. Более того, после лета 2020 года Google перестает поддерживать эту схему.
    • Неоднократно появлялись кейсы, когда версия с _escaped_fragment_ просто игнорируется Google в пользу JS-версии. Например, Юрий Хаит рассказывал о таком на F1.
    • Также страдает краулинговый бюджет, который выделяют поисковые системы на сканирование сайта — поисковому роботу приходится заходить на два URL вместо одного. При большом количестве страниц есть вероятность, что поисковой робот не будет своевременно добавлять и обновлять нужный контент.

    Когда можно использовать: нежелательно.

    Аутсорс сервисы — prerender.io и пр.

    Разработка: «Мы можем отдать рендеринг на аутсорс. Сейчас есть разные сервисы, которые предоставляют свои ресурсы (сервера) для обработки JS (рендеринга) и берут на себя демонстрацию HTML-версии страниц.. Например, prerender.io, renderjs.io».

    • Зависимость от внешних ресурсов. Если сервис лагает, придется пройти всю цепочку от фиксирования бага, общения с поддержкой до его исправления. Это долго, проект в это время не индексируется нормально.
    • Дорого на больших объемах. Например, Prerender.io, с обновлением кэша раз в сутки — 360 $/месяц (50 тыс.—100 тыс. страниц).

    Update по технологии (июль-август 2020):

    • Для рендеринга используется механизм на основе Google Chrome 61, в ближайших планах обновление до Google Chrome 67. Т.е. для рендеринга используется гораздо более современный браузер, чем в технологии WRS.
    • Более не использует _escaped_fragment для демонстрации HTML-версии страницы. На сайте до сих устаревшая информация. Боты определяются по User-Agent и им отдается HTML-версия.
    • Цена по-прежнему высока для крупных проектов: кроме озвученных на сайте тарифов — рендеринг 2 млн страниц с обновлением кэша раз в 1-3 дня, стоимость — 3,080‒9,232 $.

    Когда можно использовать: с учетом обновленных данных технология подойдет для небольших проектов.

    SSR — рендеринг на стороне своих серверов

    Разработка: «Что ж, давайте производить рендеринг на стороне наших серверов».

    SSR (Server Side Rendering) — рендеринг на стороне сервера, т.е. обработка JS кода происходит на стороне серверов клиента. Практически у всех современных JS-фреймворков и библиотек есть компонент пререндера. Например, реализация серверного рендера для Angular, React, Vue.

    Боты определяются по User-Agent и им отдается статичная HTML-версия, пользователю — динамическая (возможны вариации в виде изоморфного JavaScript, но это уже другая история).

    • Большая нагрузка на сервер.
    • Нужен высокий уровень скиллов от команды разработки, сложная задача для внедрения, которая потребует большое количество часов back-end’а.
    • Время отдачи первой версии для бота и клиента. Первый слепок должен отдаваться максимально быстро. Необходимо настраивать кеширование и своевременное обновление кеша.
    • Нужно постоянно мониторить доступность страниц (код ответа сервера), метатеги и крайне желательно сам контент на странице (может сломаться рендер блока с текстом).
    • Для безопасной работы нужно любые нововведения тестить не на боевом сервере.

    !Важно. Один из главных плюсов JS-фреймворков — его модульность — становится существенным минусом — сломаться может ЧТО угодно и КОГДА угодно.

    Бывают ситуации, когда страница отдает корректный 200ОК, но в индексе — пусто (только head и footer), или нет части контента. Может сломаться рендер блока с текстом, рендер на пагинации, рендер комментариев и т.д.

    Методология выбора типа рендеринга

    Только Google → ничего не делаем, выбираем WRS
    Нужен Google+Яндекс, небольшой проект → можно использовать аутсорс
    Нужен Google+Яндекс, большой проект → используем SSR

    Поведенческие — вишенка на торте

    Пока не ясно, что с поведенческими факторами. От слова «совсем».

    Дополнительные настройки счетчиков Метрики и Google Analytics позволяют зафиксировать перезагрузку страницы и смену URL — из этого считаются метрики глубины просмотра и времени на странице.

    Но насколько корректно все измеряется и учитывается на JS-сайтах — не ясно. В любом случае остаются не зафиксированными передвижения мыши по экрану.

    Нашей командой запущен эксперимент, который даст ответ на этот вопрос. Но это будет чуть позже, результатами обязательно поделимся!

    Общие рекомендации

    • Выбираем тип рендеринга.
    • Отдаем поисковикам рендер всей страницы. Каждой странице — отдельный URL (для этого есть компонент роутинга в JS-движке).
    • Кэп: НЕ менять структуру URL при переезде. Очень большие риски ошибки, которая наложится на все остальное. Дополнительный стресс для ПС. Если проект создается с нуля — построить всю структуру заранее.
    • Кэшируем и обновляем. Чтобы максимально быстро отдавать страницу пользователю — используем кэширование. Для снижения нагрузки на сервер кэш можно хранить на CDN.
    • Кэш на листингах/категориях/списках желательно обновлять 3-4 раза в сутки, либо после появления нового контента. Редакторские материалы можно отправлять на принудительный переобход в ПС.
    • Не используем хеш в URL (# и /#!/). Возможны проблемы с индексацией таких URL.

    Т.е. плохой URL: example.ru/#/first-page, example.ru/#!/first-page, хороший URL: example.ru/first-page

    • Используем ссылки формата a href, не onclick. Рекомендация с конференции Google.
    • Настраиваем корректный 404 ответ сервера. Для SPA-сайта это нестандартная, но выполнимая задача.

    CSS-in-JS and Static Rendering

    By James K Nelson

    CSS-in-JS can be a huge win for maintainability. But for large statically rendered websites, plain CSS still has its place.

    More and more developers are switching to CSS-in-JS, including big names like Microsoft, Atlassian, and… the Eurovision song contest! And while I haven’t always been a huge fan of CSS-in-JS, even I’m coming around to its benefits:

    • It lets you easily share variables between JavaScript and CSS (just don’t forget to escape them).
    • It’s a boon for tooling, making it easier to remove dead code, and to send the minimum amount of CSS possible.
    • And most importantly, it encourages writing CSS in a composable fashion.

    This article is based on a recent twitter thread. Speaking of twitter, if you have any questions about Static Rendering, you’re always welcome to shoot a tweet or DM at @james_k_nelson!

    It looks like CSS-in-JS will dominate the styling of web apps for the foreseeable future. But web apps only make up a fraction of the web, because content is still king — as the meteoric rise of Gatsby has made apparent.

    As a React developer, there’s as good a chance as any that you’ll be working on statically rendered web sites. And as I discovered while building create-react-blog and Frontend Armory, using CSS-in-JS for statically rendered sites still comes with a few caveats…

    #Avoiding Flashes Of Unstyled Content

    The idea behind static rendering is to speed up a site by pre-rendering the HTML for each page, which can then be displayed to users before the JavaScript finishes loading. Of course, with CSS-in-JS, your styles are in, well, the JavaScript. And this presents a problem — the initial HTML will be unstyled until the JavaScript finished loading.

    Luckily, the teams maintaining styled-components and emotion allow you to solve this with a little extra code. For instance, styled-components provides the ServerStyleSheet object, which allows you to statically render your styles at the same time as you statically render your HTML. Then, you just send the statically rendered tag as part of your HTML:

    By pre-rendering a tag and sending it with your HTML, you’ll avoid the flash of unstyled content — but there’s a catch. As ServerStyleSheet only produces styles for the initial props, any use of component state, componentDidMount or componentDidUpdate will not be reflected in the server rendered styles. Given that your pre-rendered HTML has the same constraint, this shouldn’t be a problem. But if you do need a little help fetching the initial data for each of your app’s URLs, take a look at Navi — a router that was built with static/server rendering in mind. But I digress.

    Statically rendering your styles has another benefit: it reduces the amount of CSS that’s required on each page’s initial load. This is because the rendered tags only contain the critical CSS that is required for the pre-rendered HTML. The rest of the CSS is still managed with JavaScript, letting you split it out via dynamic import() . This can be great for performance… or it can result in many megabytes of CSS that is invalidated on every update — even for updates that don’t touch the content.

    #Inline vs. External Stylesheets

    If you take a look at the generated tag in the above example, you’ll notice that it has a data-styled attribute. This is important, because it shows that styled-components is tied to that tag. You can’t reliably extract the contents of that tag into a CSS file referenced by
    . Which is… maybe not that much of a problem?

    I mean, why would you want to put your styles in a separate file anyway?

    To answer this question, consider the main reason that you’d statically render in the first place: it lets you serve JavaScript from a CDN. Now the thing about assets served from a CDN is that they’re often cached with expiry dates in the far future. As such, changes to these assets require new filenames in order to bypass the cache.

    Naturally, changes to the names of JavaScript files will require corresponding changes to the HTML that references them. As a result, your app’s HTML files can’t be cached as heavily — and neither can the tags that are embedded in them. And due to the design of Webpack, changes to any JavaScript file in your project will usually require a change to every

    SEO-тест: индексация JavaScript-сайтов

    JS-сайты и использование js фреймворков в разработке с каждым годом становятся все популярнее. В связи с этим актуальный вопрос для seo-специалистов — влияние js на seo и продвижение сайта. Мы решили провести эксперимент и проверить это в боевых условиях, создав сайты на javascript, а именно на фреймоворке vue js и проверив их индексацию.

    Что такое реактивные страницы

    Реактивные фреймворки используются для создания реактивных страниц и на данный момент завоевали большую популярность среди разработчиков. Самыми популярными на данный момент являются Angular.js, React.js, Vue.js. У каждого есть свои преимущества и недостатки, но работают они все в принципе одинаково. При загрузке страницы имеется некоторый root элемент (Примечание: root — корневой элемент — то есть элемент, внутри которого будет отрисовываться контент. ), относительно которого рендерится приложение, и содержимое изначальной верстки, например такое

    будет отрисовано и превратится в полноценную страницу, между

    Проблемы использования реактивных фреймворков

    Если просмотреть исходный html-код страницы, которая использует js фреймворк, можно увидеть весь ее изначальный шаблон с разметкой, например:

    Для функционала, не критичного к индексированию, например, личным кабинетам, административным панелям, проблема индексирования не важна, и там давно используются реактивные фреймворки, но очень заманчиво использовать их преимущества и на сайтах с контентом. Поэтому у многих возникает вопрос, как поисковый робот будет видеть данную страницу: как пользователь, с уже подставленными значениями переменных, или будет видеть весь ее исходный код.

    Как поисковики индексируют js

    К основным сложностям, связанным с JavaScript, относят:

    • Возможность доступа ботов к информации и анализа контента.
    • Возможность сканирования поисковиками.
    • Задержка загрузки (процесс визуализации веб-страниц).

    Первое время поисковики не умели индексировать js. Но уже несколько лет как эта проблема была ими решена. В 2014 году Google объявил, что может «лучше понимать веб (т.е. JavaScript)». В 2015 году Яндекс сообщил в своих новостях: «Мы начали использовать JavaScripts и CSS при обходе некоторых ресурсов для того, чтобы получить больше данных о страницах сайтов и увидеть содержимое таких сайтов в том виде, в каком оно отображается в современном браузере. Это позволяет оценить удобство интерфейса, получить контент, который ранее был недоступен роботу, и сравнить эти данные с уже используемыми при ранжировании в поиске.»

    В разделе помощи поисковых систем можно найти информацию, посвященную особенностям индексации. Например, про сайты на ajax Яндекс сообщает: «Робот Яндекса может проиндексировать AJAX-сайт, если у каждой страницы сайта есть HTML-версия.»

    AJAX, или «асинхронный JavaScript и XML» — это набор техник по веб-разработке , совмещающий JavaScript и XML, что позволяет веб-приложениям взаимодействовать с сервером в фоновом режиме. Асинхронный означает, что другие функции или линии кода могут запускаться, когда запущен скрипт async. XML некогда был основным языком передачи данных; однако AJAX используется для всех типов передачи данных (включая JSON).

    Подготовка к тестированию

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

    Зачем покупать товар?

    Товар необходимо покупать для.

    Второй — загрузить значение пременных по API. После того, как страница будет полностью загружена, отправляется запрос на получение данных c помощью ajax, и с сервера возвращаются данные в формате json.

    Признаки отсутствия асинхронной загрузки:

    Переменные инициализированы в коде, если просмотреть исходный код, то можно увидеть, чему они равны, например

    title: ‘Заголовок страницы’, ‘content’: ‘

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

    Поэтому мы подготовили два варианта текстов для тестирования, охватывающих оба этих случая.

    Проверяем индексацию js сайтов поисковыми системами

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

    Для пользователей размещенные тексты на страницах выглядят как обычно. Дополнительно мы разметили заголовок и подзаголовки с тегами h1, h2, h3.Если Вы посмотрите на такие страницы через привычный seo специалистам просмотр кода страницы, то в случае синхронной загрузки Вы увидите текст в коде, а вот в случае асинхронной загрузки — только код без видимого текста.

    Советы по технической оптимизации от представителя Google Джона Мюллера рекомендуют тестировать JS-фреймворки с помощью функции Rich Snippets в Search Console и использовать инструмент проверки структурированных данных, чтобы убедиться, что веб-сайт правильно сканируется и отображается.

    Аналогично показывает видимость кода страницы и Яндекс Вебмастер.

    В Яндекс Вебмастере один из вариантов увидеть страницу как Яндекс — посмотреть на содержимое страницы в Инструменты — Проверка ответа сервера. Здесь при синхронной загрузке видим отображение текста в содержимом. А вот для асинхронной загрузки видим только код.

    Второй вариант — посмотреть как Яндекс видит страницу — в Инструменты-Проверка мобильных страниц. И здесь уже на скриншоте видно, что Яндекс видит текст и для синхронной и для асинхронной загрузки. Для того, чтобы убедиться, что текст индексируется решаем продолжить эксперимент до его появления в поисковой выдачи.

    При использовании vue.js заголовок страницы в коде можно указать как

    title

    При генерации страницы сформируется вывод нужного заголовка. Дополнительно мы решили проверить, видят ли поисковики такие конструкции. Для этого мы создали дополнительную страницу с обычным текстом и добавили ей уникальный заголовок со словами, которые больше нигде не встречаются.

    Реализация проверки seo на vue.js

    Таймлайн проверки индексации сайтов поисковиками:

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

    В Вебмастере появилось сообщение о добавлении страниц в поиск. Проверяем поисковую выдачу.

    По запросу с асинхронной загрузкой по прежнему Яндекс не находит. По запросу с синхронной загрузкой получаем страннный результат — вместо сообщения, что слово не найдено, сообщение, о том, что запросы скрыты в связи с соблюдением законодательства РФ. Делаем скрины, отправляем вопрос поддержке Яндекса.

    Информация по поисковым запросам в Яндексе не появилась, однако предупреждение о нарушении законодательства об авторских правах исчезло.

    Мы, кстати, не первый раз сталкиваемся с тем, что при первоначальной индексации сайтов робот Яндекса может сделать самые неожиданные выводы,не имеющие с действительностью ничего общего. Решается всё обычно быстро через отправку запроса в поддержку Яндекса.

    В поиске Яндекс по запросу «брозперит» наконец появился сайт с асинхронной загрузкой. По первому сайту опять нет изменений. На всякий случай, обе его страницы несколько раз с начала эксперимента отправлялись в переобход.

    Получен ответ от поддержки Яндекса по выдаче результатов:

    Получаем через несколько дней ответ Яндекса:

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

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

    Если Яндекс считает, что сайты, релевантные ранее несуществующему и придуманному слову могут быть заблокированы предусмотрительно Роскомнадзором, не будем с ним спорить.

    Обе главных страницы сайтов появились в поиске по запросам, с ними связанными Внутренняя страница так и не появилась в Яндексе, очевидно это связано с тем, что поисковик намного медленнее Гугла добавляет страницы в поиск.

    Через несколько дней после очередного апдейта в поиске Яндекса появилась и внутренняя страница.

    Сниппеты для запросов

    С точки зрения seo, нам было также интересно, что используют поисковики в качестве сниппета для нового для них запроса, если не указывать тег description. В текстах мы использовали подзаголвки h1-h3.

    Дополнительно по обоим сайтам в Вебмастере мы запросили подбор «Рекомендованных запросов». Во-первых, мы надеялись, это быстрее покажет, что именно видит поисковик и какую семантику считает релевантной. Во-вторых, интересен был список запросов для сайта с асинхронной загрузкой.

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

    Рекомендации по seo для js

    Поисковые роботы не имеют проблем с индексацией js, если выполнены рекомендации (см. ниже). Роботы Яндекса и Google могут проиндексировать сайт с синхронной и с асинхронной загрузкой js.

    Рекомендации Google по оптимизации js сайтов, в том числе сайтов на ajax

    Как и Flash, AJAX может затруднить индексирование сайтов поисковыми системами, если эта технология реализована с ошибками. В основном AJAX вызывает две проблемы при использовании поисковых систем. Роботы поисковых систем должны «видеть» ваше содержание. Необходимо также убедиться, что они распознают правила навигации и следуют им.

    Разрабатывайте сайты на основе принципа доступности. При разработке сайта с применением AJAX подумайте, что нужно пользователям, включая тех, кто не использует браузеры с поддержкой JavaScript (например, людей, работающих с программами чтения с экрана или мобильными устройствами). Один из самых простых способов проверить доступность сайта – предварительно просмотреть его в браузере с отключенной поддержкой JavaScript или в текстовом браузере (например, Lynx). Просмотр сайта в текстовом режиме может также оказаться полезным, если необходимо выявить другое содержание, которое сложно обнаружить роботу Googlebot, например, текст, внедренный в изображения или ролики в формате Flash.

    Избегайте использования окон iFrame или создавайте отдельные ссылки на их содержание. Содержание, отображаемое с помощью iFrame, не индексируется и не показывается в результатах поиска Google. Использовать окна

    iFrame для отображения содержания не рекомендуется. Если вы применяете эту технологию, не забудьте добавить дополнительные текстовые ссылки на их содержание, чтобы робот Googlebot мог просканировать его и внести в индекс.

    Если вы начинаете создавать сайт с нуля, бывает полезно построить структуру сайта и систему навигации, используя только HTML. После того как страницы, ссылки и содержание сайта примут упорядоченный вид, можно улучшить внешний вид и интерфейс сайта с помощью AJAX. Робот Googlebot просканирует HTML, тогда как пользователи с современными браузерами смогут оценить ваши дополнения на языке AJAX.При создании ссылок следует выбрать формат, позволяющий наряду с вызовом функции JavaScript предлагать статическую ссылку. Таким образом, пользователи, включившие поддержку JavaScript, смогут применять функциональные возможности AJAX, а те, у кого нет поддержки JavaScript, смогут перейти по ссылке, не обращая внимания на сценарий. Пример.

    Обратите внимание, что URL статической ссылки содержит параметр (?foo=32), а не фрагмент ( #foo=32), используемый в коде AJAX. Это важно, поскольку поисковые системы распознают параметры URL, но часто не учитывают наличие фрагментов. Теперь вы применяете статические ссылки, так что пользователи и поисковые системы могут переходить именно к тому содержанию, к которому нужно открыть общий доступ или на которое нужно сослаться.Использование HTML-ссылок по-прежнему значительно помогает нам (а также другим поисковым системам, мобильным устройствам и пользователям) распознать структуру вашего сайта.

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

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

    Используйте атрибут rel=»canonical» для указания канонических URL, если контент размещается на нескольких URL-ах.

    Избегайте использования AJAX-подобных механизмов сканирования. Это — самая распространенная ошибка, которую допускают специалисты при смене подходов к программированию сайтов. Не забудьте удалять тег «meta fragment» из копии HTML AJAX страниц. Никогда не используйте данный тип тегов, если на странице применяется тег «escaped fragment».

    Не используйте в URL-ах символ «#», Google очень редко индексирует такие адреса. Структура «стандартного» адреса страницы должна строиться по принципу: путь/имя файла/параметры запроса, за исключением тех случаев, когда для расширения возможностей навигации используется объект History API.

    Чаще применяйте инструмент «Сканер Google для сайтов», доступный в Search Console. Он позволит вам лучше понять, какими видят страницы сайта алгоритмы поискового робота Googlebot. Имейте в виду инструмент не поддерживает URL-ы, содержащие символы «#!» или «#».

    Убедитесь в том, что все запрашиваемые ресурсы, включая файлы javascript, фреймворки, ответы сервера, сторонние API и т.д., не закрыты в файле robots.txt. «Сканер Google для сайтов» покажет вам список ресурсов, закрытых от индексации. Если они были закрыты в файле robots.txt (это часто происходит со сторонними API) или временно недоступны по другим причинам, важно дополнительно убедиться в том, что код работает страницы исполняется корректно.

    Google поддерживает использование javascript для создания тайтлов, метаописаний и мета-тегов robots, структурированных данных, и других видов мета-данных. Во всех случаях использования формата AMP страница AMP HTML должна быть статической. В то же время, при создании веб-страниц допустимо использовать элементы JS/PWA. Не забывайте создавать файлы sitemap с применением тега тег — это укажет поисковому роботу, что на сайте производились изменения.

    Рекомендации Яндекса для Ajax сайтов

    Робот Яндекса может проиндексировать AJAX-сайт, если у каждой страницы сайта есть HTML-версия.

    Обычно, чтобы указать роботу предпочитаемую для использования в результатах поиска версию, нужно добавить в HTML-код страницы, которая не должна участвовать в поиске, ссылку на нужную страницу с атрибутом rel=»canonical». Этот атрибут может помешать роботу корректно проиндексировать HTML-версию AJAX-страницы, поэтому не используйте его для страниц, которые должны участвовать в поиске.

    Вы можете сообщить роботу о HTML-версии страницы с помощью:

    Добавьте в код AJAX-страницы метатег meta name=»fragment» content=»!». В итоге HTML-версия этой страницы должна быть доступна по адресу с добавлением параметра ?_escaped_fragment_=(значение параметра пустое).

    Не размещайте метатег в HTML-версии страниц сайта — робот не сможет проиндексировать ее.

    2) Параметра в адресе страницы

    Добавьте в адрес AJAX-страницы параметр #!. В итоге HTML-версия этой страницы должна быть доступна по адресу, в котором сочетание #!заменено на параметр ?_escaped_fragment_=. Например: адрес http://www.example.com/#!blog должен измениться на адрес http://www.example.com/?_escaped_fragment_=blog.

    Cсылки, содержащие #!, также можно использовать в карте сайта.

    Чтобы робот быстрее узнал о страницах сайта, отправьте на переобход HTML-версии страниц. Когда HTML-страницы появятся в результатах поиска, ссылки будут перенаправлять пользователей на AJAX-страницы сайта.

    Дополнительные особенности индексации

    Влияние не тестировалось в ходе эксперимента, но можно предположить, что обфускация js не будет влиять на индексацию (теоретически, конечно, могут быть исключения). Обфускация — это приведение исходного текста программы к виду, сохраняющему ее функциональность, но затрудняющему анализ, понимание алгоритмов работы и модификацию при декомпиляции. Цель обфускации js — затруднениe изучения/понимания javascript-кода. JavaScript выполняется на стороне браузера. Даже на довольно старых (более 2х лет назад) форумах можно найти сообщения о том, что поисковики индексируют обфусцированный код.

    Сжатие js не влияет на индексацию. Скорее наоборот — это приведет к ускорению загрузки страницы и положительно повлияет на индексирование поисковыми системами. Сжатие js — постоянная рекомендация для сайтов в Google PageSpeed.

    Ускорение индексации сайта на js

    — лайфхак от Дэвида Кюннена

    В январе 2020 года Дэвид Кюннен, специалист из Германии, опубликовал итоги своего тестирования по ускорению индексации сайта на js — «Как добавить 250 тысяч страниц в индексацию Google» («How to get 250k+ pages indexed by Google»). Сайт, о котором речь в статье, был разработан с React App на фронтенде.

    В ходе тестирования вначале был настроен SSR — серверный рендеринг. Кюннен исходил из предположения, что рендеринг для SPA-сайтов (Single Page Applications) помогает роблотам сразу видеть все ссылки в коде без двойного прохода по коду. Внедрение рендеринга на сайте позволило ему увеличить скорость обхода страниц Google, но незначительно. В комментариях к публикации также рассматривается альтернатива SSR — использование пререндерера.

    Значительного, в несколько раз, увеличения скорости индексирования удалось добиться отключением js для бота.

    Поисковик выделяет ограниченное количество ресурсов для индексации конкретного сайта. Несмотря на то, что Google видит все ссылки в начальном HTML, но он все равно отправляет все в свой рендерер, чтобы убедиться, ничего ли не осталось для индексации — из-за наличия в коде JavaScript не понимая, все ли находится в начальном HTML. Сразу же после этих изменений скорость обхода Google увеличилась до 5-10 страниц в секунду.

    Итоговая рекомендация от Дэвида Кюннена: Если вы хотите, чтобы Google проиндексировал ваш большой сайт, отдавайте ему сразу финальный HTML, и удалите весь JavaScript (конечно же, за исключением Schema-JS).Подробнее об ускорении js сайтов и о том, не воспримут ли поисковые системы такую отдачу содержимого сайта как манипулирование и подмену информации сайта для поисковиков, относимых к черным методам оптимизации, читайте в нашей статье «Ускорение индексации js сайта».

    Оказывается, нет. https://developers.google.com/search/docs/guides/dynamic-rendering В статье Google рекомендует использовать динамическое отображение контента. Оно дает возможность предоставлять некоторым агентам пользователя контент страницы, предварительно обработанный на сервере. Для работы динамического отображения ваш сервер должен распознавать поисковых роботов (например, проверяя агент пользователя). Запросы от роботов передаются средству отображения, а запросы от пользователей обрабатываются обычным образом. При необходимости средство динамического отображения возвращает версию контента, которая может быть обработана роботом, например статическую HTML-страницу.

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

    Резюме

    Как и ожидалось, Google индексирует и выводит страницы в поисковой выдаче в несколько раз быстрее Яндекса.

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

    Страницы js сайтов корректно индексируются поисковыми системами независимо от синхронной или асинхронной загрузки.

    На индексацию влияют также корректность чпу и их соответствие правилам поисковых систем.

    Специалисты APRIORUM всегда помогут вам выполнить грамотную оптимизацию любого сайта с учетом особенностей кода сайта и задач бизнеса.

    Материал опубликован пользователем.
    Нажмите кнопку «Написать», чтобы поделиться мнением или рассказать о своём проекте.

    Топ-пост этого месяца:  Принудительное выделение блока с текстом
    Добавить комментарий