Ssr что это значит

Server-Side Rendering с нуля до профи

  • В данной статье мы разберем влияние SSR на SEO оптимизацию приложения.
  • Пройдем с вами путь по переносу обычного React приложения на SSR.
  • Разберем обработку асинхронных операций в SSR приложениях.
  • Посмотрим, как делать SSR в приложениях с Redux Saga.
  • Настроим Webpack 5 для работы с SSR приложением.
  • А также рассмотрим тонкости работы SSR: Генерация HTML Meta Tags, Dynamic Imports, работа с LocalStorage, debugging и прочее.

Пару лет назад, работая над своим продуктом Cleverbrush мой друг и я столкнулись с проблемой SEO оптимизации. Созданный нами сайт, который по идее должен был продавать наш продукт, а это был обычный Single Page React Application, не выводился в Google выборке даже по ключевым словам! В ходе детального разбора данной проблемы родилась библиотека iSSR, а также наш сайт начал появляться на первой странице Google. Итак, давайте по порядку!

Проблема

Главной проблемой Single Page приложений является то, что сервер отдает клиенту пустую HTML страницу. Её формирование происходит только после того как весь JS будет скачан (это весь ваш код, библиотеки, фреймверк). Это в большинстве случаев более 2-х мегабайт размера + задержки на обработку кода.

Читайте также:  Относительное количество гранулоцитов повышен у женщин что это значит

Даже если Google-бот умеет выполнять JS, он получает контент только спустя некоторое время, критичное для ранжирования сайта. Google-бот попросту видит пустую страницу несколько секунд! Это плохо!

Google начинает выдавать красные карты если ваш сайт рендерится более 3-х секунд. First Contentful Paint, Time to Interactive — это метрики которые будут занижены при Single Page Application. Подробнее читайте здесь.

Также есть менее продвинутые поисковые системы, которые попросту не умеют работать с JS. В них Single Page Application не будут индексироваться.

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

Рендеринг

Существует несколько путей как решить проблему пустой странички при загрузке, рассмотрим несколько из них:

Static Site Generation (SSG). Сделать пререндер сайта перед тем как его загрузить на сервер. Очень простое и эффективное решение. Отлично подходит для простых веб страничек, без взаимодействия с backend API.

Server-Side Rendering (SSR). Рендерить контент в рантайме на сервере. При таком подходе мы сможем делать запросы backend API и отдавать HTML вместе с необходимым содержимым.

Server-Side Rendering (SSR)

Рассмотрим подробнее, как работает SSR:

  • У нас должен быть сервер, который выполняет наше приложение точно так же, как делал бы это пользователь в браузере. Делая запросы на необходимые ресурсы, отображая весь необходимый HTML, наполняя состояние.
  • Сервер отдает клиенту наполненный HTML, наполненное состояние, а также отдает все необходимые JS, CSS и прочие ресурсы.
  • Клиент, получая HTML и ресурсы, синхронизирует состояние и работает с приложением как с обычным Single Page Application. При этом важным моментом является то, что состояние должно синхронизироваться.

Схематично SSR приложение выглядит вот так:

Из вышеописанной работы SSR приложения мы можем выделить проблемы:

  • Приложение делится на сервер и клиент. То есть у нас по сути получается 2 приложения. Данное разделение должно быть минимально иначе поддержка такого приложения будет сложной.
  • Сервер должен уметь обрабатывать запросы к API с данными. Данные операции асинхронные, являются Side Effects. По умолчанию renderToString метод React работающий с сервером — синхронный и не может работать с асинхронными операциями.
  • На клиенте приложение должно синхронизировать состояние и продолжать работать как обычное SPA приложение.

Это маленькая библиотека которая способна решить проблемы асинхронной обработки запросов к данным а также синхронизации состояния с сервера на клиент. Это не “очередной убийца Next.JS”, нет! Next.JS прекрасный фреймверк имеющий множество возможностей, но чтобы его использовать вам придется почти полностью переписать ваше приложение и следовать правилам Next.JS.

Посмотрим на примере, как просто перенести обычное SPA приложение на SSR.

К примеру, у нас есть простейшее приложение с асинхронной логикой.

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

Сделаем данное приложение SSR!

Шаг 1. Установка зависимостей

Для установки iSSR нужно выполнить:

Для настройки базовой билд системы установим:

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

Для сервера будем использовать express, но это не важно, можно использовать любой другой фреймверк:

Добавим модуль для сериализации состояния приложения на сервере:

Шаг 2. Настройка webpack.config.js

  • Для компиляции SSR приложения конфигурационный файл webpack должен состоять из двух конфигураций (MultiCompilation). Одна для сборки сервера, вторая для сборки клиента. Мы передаем в module.exports массив.
  • Для конфигурации сервера нам нужно задать target: ‘node’. Для клиента задавать target не обязательно. По умолчанию конфигурация webpack имеет target: ‘web’. target: ‘node’ позволяет webpack обрабатывать сервер код, модули по умолчанию, такие как path, child_process и прочее.
  • const commonConfig — общая часть настроек. Так как код сервера и клиента имеет общую структуру приложения, они должны обрабатывать JS одинаково.

В babel-loader необходимо добавить плагин:
@issr/babel-plugin
Это вспомогательный модуль @issr/babel-plugin позволяющий отследить асинхронные операции в приложении. Замечательно работает с babel/typescript-preset, и прочими babel плагинами.

Шаг 3. Модификация кода

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

Мы поменяли стандартный render метод React на hydrate, который работает для SSR приложений.

В коде сервера обратите внимание, что мы должны расшаривать папку с собранным SPA приложением webpack:
app.use(express.static(‘public’));
Таким образом, полученный с сервера HTML будет работать далее как обычный SPA

Шаг 4. Обработка асинхронности

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

Для обработки асинхронных операций их нужно обернуть в хук useSsrEffect из пакета @issr/core:

В server.jsx заменим стандартный renderToString на serverRender из пакета @issr/core:

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

В App.jsx заменим стандартный setState на useSsrState из пакета @issr/core:

Внесем изменения в client.jsx для синхронизации состояния переданного с сервера на клиент:

window.SSR_DATA — это объект, переданный с сервера с кешированнным состоянием, для синхронизации на клиенте.

Сделаем передачу состояние на сервере:

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

Шаг 5. Билд скрипты

Осталось добавить скрипты запуска в package.json:

Redux и прочие State Management библиотеки

iSSR отлично поддерживает разные state management библиотеки. В ходе работы над iSSR я заметил, что React State Management библиотеки делятся на 2 типа:

  1. Реализует работу с Side Effects на слое React. Например Redux Thunk превращает вызов Redux dispatch в асинхронный метод, а значит мы можем имплементить SSR как в примере выше для setState. Пример с redux-thunk доступен по ссылке
  2. Реализуют работу с Side Effects на отдельном от React слое. Например Redux Saga выносит работу с асинхронными операциями в Саги.

Рассмотрим пример реализации SSR для приложения с Redux Saga.

Мы не будем рассматривать этот пример так детально как предыдущий. Ознакомится с полным кодом можно по ссылке.

Redux Saga

*Для лучшего понимания происходящего, читайте предыдущую главу

Сервер запускает наше приложение через serverRender, код выполняется последовательно, выполняя все операции useSsrEffect.

Концептуально Redux работая с сагами не выполняет никаких асинхронных операций. Наша задача отправить action для старта асинхронной операции в слое Саг, отдельных от нашего react-flow. В примере по ссылке выше, в контейнере Redux мы выполняем

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

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

Я подготовил много примеров использования iSSR, вы можете их найти по ссылке.

SSR трюки

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

HTML Meta Tags для SSR

Немаловажным аспектом в разработке SSR является использование правильных HTML meta tags. Они сообщают поисковому боту ключевую информацию на странице.
Для реализации данной задачи рекомендую использовать один из модулей:
React-Helmet-Async
React-Meta-Tags
Я подготовил несколько примеров:
React-Helmet-Async
React-Meta-Tags

Dynamic Imports

Чтобы снизить размер финального бандла приложения, принято приложение делить на части. Например dynamic imports webpack позволяет автоматически разбить приложение. Мы можем вынести отдельные страницы в чанки или блоки. При SSR мы должны уметь обрабатывать данные фрагменты приложения как одно целое. Для этого рекомендую использовать замечательный модуль @loadable

Dummies

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

localStorage, хранение данных

NodeJS не поддерживает localStorage. Для хранения сессионных данных мы используем cookie вместо localStorage. Файлы cookie отправляются автоматически по каждому запросу. Файлы cookie имеют ограничения, например:

  • Файлы cookie — это старый способ хранения данных, они дают ограничение в 4096 байт (фактически 4095) на один файл cookie.
  • localStorage — это реализация интерфейса хранилища. Он хранит данные без даты истечения срока действия и очищается только с помощью JavaScript или очистки кеша браузера / локально сохраненных данных — в отличие от истечения срока действия файлов cookie.

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

React Server Components

React Server Components возможно будет хорошим дополнением для SSR. Его идеей является снижение нагрузки на Bundle за счет выполнения компонент на сервере и выдачи готового JSON React дерева. Нечто подобное мы видели в Next.JS. Читайте подробнее по ссылке

Роутинг

React Router из коробки поддерживает SSR. Отличие в том, что на server используется StaticRouter с переданным текущим URL, а на клиенте Router определяет URL автоматически при помощи location API. Пример

Debugging

Дебаг на сервере может выполняться также как и любой дебаг node.js приложений через inpsect.
Для этого нужно добавить в webpack.config для nodejs приложения:

devtool: ‘source-map’
А в настройки NodemonPlugin:

Также, для улучшения работы с source map можно добавить модуль

В nodeArgs опций NodemonPlugin добавить:
‘—require=«source-map-support/register»’
Пример

Next.JS

Если вы создаете приложение с нуля, рекомендую обратить внимание на данный фреймверк. Это самое популярное решение на данный момент для создания с нуля приложений с поддержкой SSR. Из плюсов можно выделить то, что все идет из коробки (билд система, роутер). Из минусов — необходимо переписывать существующее приложение, использовать подходы Next.JS.

SEO это не только SSR!

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

Для проверки вашего сайта при SEO оптимизации можно воспользоваться:

Источник

В чем суть SSR (Server Side Rendering)?

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

Ведь, если я не ошибаюсь, суть подхода в том, что сначала один js получает от другого js, некий json, конвертит его в строку, и вставляет в хтмл.
Тут вопрос. А зачем? Если сервер мог сразу сгенерить страницу с итоговым хтмл.

Получается нужно знать express, babel, webpack, какой нибудь там next/nuxt или как их там. Или же просто взять и на условном рнр, без знаний десятка доп технологий, написать index.php, в котором уже будет всё сгенерировано и так же отдано пользователю.

  • Вопрос задан 28 апр.
  • 247 просмотров

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

Если вы пользуетесь фреймворками Vue/React то для них есть решения Nuxt.js/Next.js которые являются по сути обертками удобно реализующими SSR этиъх приложений. Что касается терминов, Express в случае этих решений вам не понадобится. А вот babel, webpack в любом случае придется использовать, так как они нужны для работы не только SSR но и сборки и работоспособности клиентского JS

Ну я на самом деле и не говорил про SSR на PHP. РНР я привел как пример «старого» подхода.

И как раз вопрос в том, зачем эти «новые подходы» нужны. Например, мы писали SPA еще лет 10 назад, используя PHP + Jquery. И как бы этот вариант идеально воспринимали поисковики даже в те времена.

А сейчас слышу как восторгаются тем, что появились технологии позволяющие формировать html на стороне сервера. И не понимаю в чем прикол.

И вот не пойму — получается то, что мы делали самописные SPA через PHP+Jquery — это было SSR? А зачем сложности с JSON и прочими вроде бы лишними историями?

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

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

Так а ведь любой старый сайт работает так же, нет? Отдает сразу читаемый вид html. Будь то рнр или что еще.

Или эта вся история с SSR чисто для сайтов полностью на JS? Хотя и тут мимо. Я 5 лет назад писал на ноде, и тоже передавал пользователю с сервера полную хтмл страничку.

Источник

Оцените статью